Object and wrapper classes

Objects have two lifeforms, literal and instantiated, and the most common is literal.

var obj = {}; // the literal form
var obj = new Object(a);// Instantiation mode
Copy the code

Add, delete, modify and check object attributes:

var obj = {
  name: 'zhangsan'
};

// create
obj.gender = 'male';

// read
obj.name;

// update
obj.name = 'lisi';

// delete
delete obj.gender;
Copy the code

Custom methods instantiate objects, and each object is unique

function Person() {}var person = new Person(); 
Copy the code

Object naming conventions: Big camel name (functions are small camel name)

What happens when an object instantiates

After using the new operator

1. Implicitly add this = {} to the front of the function body.

2, execute this. XXX = XXX assignment statement

3. Implicitly return this

function Person(name) {
  // var this = {};
  this.name = name;
  
  // return this;
}
Copy the code

Following this logic, the following can also simulate implementing the new operator.

function Person(name) {
  var that = {};
  
  that.name = name;
  
  return that;
}
Copy the code

For an object that uses an instance of the new keyword, the value of its internal return is ignored. For example,

function Person(name) {
  
  this.name = name;
  
  return 1111;
}

var person = new Person('111'); // person => {name: '111'}
Copy the code

A wrapper class

As we all know, primitive values have no methods and attributes, but we can always add attributes to primitive values, such as:

var num = 4;
num.abc = 'sad';
console.log(num.abc); // undefined
Copy the code

The above operation of adding attributes to raw values and accessing them can actually be divided into two steps

new Number(num).abc = 'sad'
console.log(new Number(num).abc)
Copy the code

Same for string access to its length attribute

var str = '1234';console.log(str.length); // This step is actually new String(STR).length
Copy the code

The prototype

The prototype can be understood as the ancestor of the object. What the ancestor has, the son and grandson can also inherit.

A stereotype is a property of the function object that defines the public ancestor of the function that the leiler constructor produces. The object generated by this constructor can integrate properties and methods on the stereotype, which is also an object

function Person(){
    
}
Person.prototype.firstName = 'zhang';
var person = new Person();
person.firstName // zhang
Copy the code

Add, delete, change and check the prototype:

Person.prototype.lastName = 'san';
function Person(firstName) {
    this.firstName = firstName;
}
var person = new Person('zhang');

// create, where a property is created for the object and the property is created on the prototype
person.gender = 'male'

// create, which adds a property to the prototype
person.__proto__.gender = 'female'

// delete, delete can only delete its own and its prototype attributes
delete person.firstName

// update
person.firstName = 'female'
person.__propto__.lastName = 'zhangsan'

// read
person.firstName
person.__proto__.fistName
Copy the code

Object access attribute rule: If it can’t find it, look up the prototype chain until it finds the attribute or reaches Object.__proto__.

function Person() {}
Person.prototype.name = 'zhangsan'
var person = new Person();
Person.prototype = {
    name: "lisi"};Copy the code

The above is similar to the following example

var obj = {name: 'a'}
var obj1 = obj;
obj = {name: 'b'}
Copy the code

So person.name = ‘zhangsan’

In addition, this situation is different

function Person(a) {}
Person.prototype.name = 'zhangsan'
Person.prototype = {
    name: "lisi"};var person = new Person();
Copy the code

Person. name=’lisi’ because person. prototype changed the reference early

Prototype chain

function Grand() {
}
Grand.prototype.lastName = 'zhangsan'
var grand = new Grand()

function Father() {
    this.firstName = 'lisi'
}
Father.prototype = grand;
var father = new Father();

function Son() {
    this.hobbit = 'trip'
}

Son.prototype = father;
var son = new Son();

console.log(son);
Copy the code

The prototype tells us that if an object cannot find a property at the moment, it will follow its protoyoe= until it finds or ends. So here son.lastName is actually son.__proto__.__proto__.__proto__

In this way, a prototype chain is formed by stringing one prototype after another.

Object. Create (null) {Object. Create (null) {Object.

function Person(a) {
    this.name = 'zhangsan'
}
Person.prototype = {
    name: '111',
    say: function () {
        console.log(this.name); }}var p = new Person();
p.__proto__.say();
p.say();
Copy the code

In this case, according to the attribute search rules of prototype chain, the first one will search the name in prototype for printing, while in the second case, the name of Person itself will be directly printed since person already has a name. From this point of view, a rule can be summarized. Without changing the direction of this, whoever calls this belongs to the same person (of course, if they cannot find it, they will still look for the prototype chain).

Object.create(obj) : Creates an Object based on the parameter obj. When obj is null, the Object has no prototype

There is only undefined, null and no stereotype in the base type of data

Functions such as toString in the underlying data type that are overridden will not be called when they are called

The call, the apply

Call and apply change the direction of this. The difference lies in the way the arguments are passed: the apply argument is passed through the array, and the call argument is passed one by one

function Person(name) {
    this.name = name;
    this.say = function (a, b, c) {
        console.log(this.name); }}var person = new Person('lisi');
var obj = {
    name: 'zhangsan'
};
person.say.call(obj, '111'.'2232'.'3333'); // zhangsan
person.say.call(person); // lisi
person.say.apply(obj, ['111'.'2232'.'3333']); // zhangsan
Copy the code

You can use Call and apply to borrow other constructors for your own needs

function Person(name, age) {
    this.name = name;
    this.age = age;
}
function Student(name, age, grade, tel) {
    Person.call(this, name, age);
    this.grade = grade;
    this.tel = tel;
}
var stu = new Student("Zhang".17.1."1111");
console.log(stu);
Copy the code