Объекты

Объекты. Свойства. Объекты среды.

Мангин Александр

В прошлых сериях.

Мы поговорили про это..

Введение

Java Script - это...

  • Императивный ЯП
  • Функциональный ЯП
  • Объектный ЯП

Java

Все объект!

JavaScript

Все объект!

... почти все

Типы данных

  • Число
  • Строка
  • Null
  • Undefined
  • Boolean
  • Object

Типы данных

  • Примитивные типы данных
  • Объекты

В чем разница?

  • Объекты имеют методы
  • А структуры нет

В чем разница?


var student = {
    wakeUp: function() {
        console.log('Я НЕ СПЛЮ!');
    };
};

student.wakeUp();
                

// 'Я НЕ СПЛЮ!'
                

В чем разница?


var answer = 42;

answer.toFixed(2);
                

// 42.00
                

То есть числа - это объекты?

Нет

В чем разница?


var answer = 42;

answer.toFixed(2);
                

var answer = 42;

(new Number(answer)).toFixed(2);
                

А может я вас обманываю?


var answer = 42;

answer.secret = 'немного магии';

answer.secret;
                

undefined;
                

А может я вас обманываю?


var answer = 42;

(new Number(answer))
    .secret = 'немного магии';

answer.secret;
                

undefined;
                

А как мне сохранить секрет?


var answer = new Number(42);

answer.secret = 'немного магии';

answer.secret;
                

'немного магии';
                

Number

Функция-конструктор

Number: обычный вызов


var answer = '42';

Number(answer);
                

// 42
                

Number: вызов через 'new'


var answer = '42';
var result = new Number(answer);

result;
                

// Number {[[PrimitiveValue]]: 42}
                

Объекты-оболочки


var answer = '42';
var result = new Number(answer);

result == 42;
result === 42;
typeof result;
                

// true
// false
// object
                

Конструкторы примитивных типов

  • Number
  • Boolean
  • String

Где можно встретить объекты-оболочки:

  • Случайно написали new Number('42')
  • Пришли на собеседование :)

Когда-то нужно использовать?

Никогда

Хитрый пример


var isChecked = new Boolean(false);

if (isChecked) {
    console.log('checked');
} else {
    console.log('unchecked');
}
                

// checked
                

Объект

Создание объекта:

  • Литерал
  • Конструктор
  • Object.create

Литерал


var empty = {};

var driver = {
    'first name': 'Max',
    skills: {
        mad: 1000
    }
};
                

Конструктор


var empty = new Object();
                

Object.create


var empty = Object.create(null);
                

Какой способ лучше?

{}

Свойства

Получение свойств


var student = {
    id: 1,
    'full name': 'Alex'
};

student.id;
student['id'];
student['full name'];

// 1
// 1
// 'Alex'

Установка значений


var student = {
    id: 1,
    'full name': 'Alex'
};

student.score = 1;
student['score'] = 1;
student['full name'] = 'Max;

Ошибки доступа к полям


var student = {
    id: 1,
    'full name': 'Alex'
};

student.score;
student.score.toFixed(2);

// undefined
// TypeError

Удаление свойств


var student = {
    id: 1,
    score: 1,
    'full name': 'Alex'
};

delete student.score;

Проверка наличия свойства


var student = {
    id: 1,
    score: 1,
    'full name': 'Alex'
};

'id' in student;
student.hasOwnProperty('score');

Проверка наличия свойства

Лучше .hasOwnProperty()

getter/setter


var student = {
    name: 'Alex',
    surname: 'Mangin'
};

var student = {
    getFullName: function() {
        return this.name +
            ' ' + this.surname;
    },
    setFullName: function (value) {
        var parts = value.split(' ');
        this.name = parts[0];
        this.surname = parts[1];
    }
};

student.getFullName();
student.setFullName('Max Maxes');

var student = {
    get fullName() {
        return this.name +
            ' ' + this.surname;
    },
    set fullName(value) {
        var parts = value.split(' ');
        this.name = parts[0];
        this.surname = parts[1];
    }
};

student.fullName;
student.fullName = 'Max Maxes';

Что такое свойство?

Это объект

  • Имя
  • Значение
  • Набор аттрибутов

Object.defineProperty(obj, prop, descriptor)

  • obj - объект
  • prop - имя свойства
  • descriptor - набор аттрибутов

Descriptor

  • value
  • get
  • set
  • configurable
  • enumerable
  • writable

Descriptor: value


var student = {
    name: 'Alex',
    surname: 'Mangin'
};

Object.defineProperty(student,
    'score', {value: 42});
            

student.score = 42;
            

Descriptor: configurable


var student = {
    name: 'Alex',
    surname: 'Mangin'
};

Object.defineProperty(student,
    'score', {
    value: 42,
    configurable: false
});
            

delete student.score;
student.score; // 42
            

Descriptor: enumerable


var student = {};

Object.defineProperty(student,
    'score', {
    value: 42,
    enumerable: false
});
            

Object.keys(student); // []
for (var x in student) {
    console.log(x);
}
            

Descriptor: writable


var student = {
    name: 'Alex',
    surname: 'Mangin'
};

Object.defineProperty(student,
    'score', {
    value: 100500,
    writable: false
});
            

student.score = 0;
student.score; // 100500
            

Descriptor: set/get


var student = {
    _score: 0
};

Object.defineProperty(student,
    'score', {
    set: function (rawValue) {...},
    get: function () {...}
});
            

Default Descriptor


Object.defineProperty({},
    'score', {
    configurable: false,
    enumerable: false,
    writable: false,
    value: undefined,
    set: undefined,
    get: undefined
});
            

Default Descriptor при присваивании


Object.defineProperty({},'score',
    {
    configurable: true,
    enumerable: true,
    writable: true,
    value: 'Ваше значение',
    set: undefined,
    get: undefined
});
            

Нужно ли их использовать?

Все зависит от вас!

Полифилы


var fns = Array.prototype;
var define = Object.defineProperty;
            

fns.forEach = function () {
    // ваша реализация
}
            

define(fns, 'forEach', {
    value: function() {};
    enumerable: false,
    writable: true,
    configurable: true
});
            

Сериализация


var student = {
    name: 'Alex',
    surname: 'Mangin'
}
            

JSON.stringify(student);
// {"name":"Alex",
// "surname":"Mangin"}
            

Сериализация


var student = {
    privateData: {secret: '42'}
}
            

JSON.stringify(student,
    function (key, value) {
        if (key === 'privateData') {
            return null;
        }
        return value;
});
// {"privateData":null}
            

Проблемы сериализации


var student = {};
student.self = student;

JSON.stringify(student);
            

// Uncaught TypeError: Converting
// circular structure to JSON
            

Проблемы сериализации


var student = {
    print: function () {
        console.log('Mangin Alex');
    },
    regexp: /d+/
};

JSON.stringify(student);
            

{"regexp":{}}
            

Обход при сериализации

В ширину

Десериализация


var rawStudent =  '{"name":"Alex"}';
            

JSON.parse(rawStudent);
            

Десериализация


var rawStudent='{"name":"Alex", ' +
    '"_meta"="student"}';
            

function deserialize (key, value) {
  if (key === '' &&
      value._meta === 'student') {
    return createStudent(value);
  }
  return value;
}

JSON.parse(rawStudent, deserialize);
            

Обход при десериализации

В глубину

Массивы

forEach


var numbers = [1, 1, 2, 3, 5];

for (var i = 0 ; i < 5; i ++) {
    console.log(numbers[i]);
});

            

numbers.forEach(function (n) {
    console.log(n);
});
            

map


var numbers = [1, 1, 2, 3, 5];
var result = []

for (var i = 0 ; i < 5; i ++) {
    result.push(numbers[i]*numbers[i])
});
            

var result = numbers.map(function (n) {
    return n*n;
});

var numbers = [1, 1, 2, 3, 5];
var result = []
for (var i = 0 ; i < 5; i ++) {
    if (numbers[i] % 2 === 0) {
        result.push(numbers[i]);
        break;
    }
});
            

var result = numbers.filter(function (n) {
    return n % 2;
});

var numbers = [1, 1, 2, 3, 5];
var isBiggerThanTen = false;

for (var i = 0 ; i < 5; i ++) {
    if  (numbers[i] > 10) {
        isBiggerThanTen = true;
        break;
    }
});
            

var result = numbers.some(function (n) {
    return n > 10;
});

var numbers = [1, 1, 2, 3, 5];
var isBiggerThanTen = true;

for (var i = 0 ; i < 5; i ++) {
    if(numbers[i] >= 10) {
        isBiggerThanTen = false;
        break;
    }
});
            

var numbers = [1, 1, 2, 3, 5];

var result = numbers.every(function (n) {
    return n < 10;
});

var numbers = [1, 1, 2, 3, 5];
var dict = {};

for (var i = 0 ; i < 5; i ++) {
    dict[i] = numbers[i]*numbers[i];
});
            

function callback(dict, value) {
    dict[value] = value * value;
    return dict;
}

var result =
    numbers.reduce(callback, {});

Date

Date


var now = new Date();
            

Date


// 24 часа после 01.01.1970 GMT+0
var jan02_1970
    = new Date(3600 * 24 * 1000);
            

Date


var now = new Date(year, month,
    date, hours, minutes,
    seconds, ms);
// year > 1970
// month >= 0
            

Получение компонента Date


var date = new Date();
date.getFullYear(); // год
date.getMonth(); // месяц
date.getDate(); // день
date.getHours(); // час
date.getMinutes(); // минуты
date.getSeconds(); // секунды
date.getMilliseconds(); // милисекунды
date.getDay(); // день недели
            

Получение компонента Date


var date = new Date();
date.getUTCFullYear(); // год
date.getUTCMonth(); // месяц
date.getUTCDate(); // день
date.getUTCHours(); // час
date.getUTCMinutes(); // минуты
date.getUTCSeconds(); // секунды
date.getUTCMilliseconds(); // милисекунды
date.getUTCDay(); // день недели
            

getTime()


var date = new Date();
date.getTime();
            

getTimezoneOffset()


var date = new Date();
date.getTimezoneOffset(); // -300
            

Date.now()


Date.now(); // 1446448043192
            

Установка полей Date


var date = new Date();
date.setFullYear(2014);
date.setMonth(2);
date.setDate(12);
date.setHours(10);
date.setMinutes(23);
date.setSeconds(60);
date.setMilliseconds(500);
            

Автоисправление Date


var date = new Date(2013, 0, 32);
// 32 января 2013 ?!?
            

date;
// ... это 1 февраля 2013!
            

Профилирование кода


var start = Date.now()

// ваш код

var end = Date.now();
console.log(end - start);
            

Профилирование кода


console.time('test1')

// ваш код

console.timeEnd('test1');
            

Десериализация Date


var date = Date.parse('some date');
            
  • YYYY-MM-DD
  • THH:mm:ss.sss
  • Z+-hh:mm

Десериализация Date


Date.parse('2012-01-26'+
    'T13:51:50.417');
Date.parse('2012-01-26');
Date.parse('2012-01-26'+
    'T13:51:50.417Z10:30');
            

Math

Константы


Math.E; // 2,718
Math.LN2; // ln 2  0,693.
Math.LN10; // ln 10 2.303.
Math.LOG2E; // log(2, e) 1.443
Math.LOG10E; // log(10, e) 1.443
Math.PI; // 3.14
Math.SQRT1_2; // sqrt(1/2) 0,707.
Math.SQRT2; // sqrt(2) 1.414
            

Функции


Math.sign(x);
Math.abs(x);
Math.floor(x);
Math.round(x);
Math.log(x);
Math.max(a,b,c, ...);
Math.min(a,b,c ...;
Math.random();
Math.sqrt(x);
            

Функции


Math.cos(x);
Math.sin(x);
Math.tan(x);
            

Домашнее задание