JavaScript object, this and three properties

JavaScript object

Introduction

In JavaScript, an object is an unordered collection of related properties and methods. All things are objects, such as strings, values, arrays, functions, etc.

In Javascript, almost all transactions are objects. An object can also be a variable, but it can include multiple values. It exists in the name:valueform of (it can be said that an object is a container for variables, encapsulating properties and methods)

var car = {
    
    
    name:value
}
// 这种形式和python的字典相像

There are three types of objects in JavaScript:

  • custom object
  • Built-in objects (such as date, math, array, etc.)
  • Browser objects (such as Window objects, Document objects , History objects, etc.)

How to create an object

1. Create it in the form of name:value

var star = {
    
    
    name : 'xxxx',
    age : 'xx',
    sex : 'xx',
    fun : function(){
    
    
        alert('xxxx');
    }
};

typeof this.star //=> 'object'

2. Use new object to create objects

var star = new Object();
star.name = 'xxxx';
star.age = 'xx';
star.sex = 'xx';
star.fun = function(){
    
    
    alert('xxxx');
}

console.log(typeof star); //=> Object

3. Create objects using constructors

var star = function(){
    
    
    this.name = 'xxxx',
    this.age = 'xx',
    this.sex = 'x',
    this.fun = function(){
    
    
        alert('xxxx');
    }
};

var p = new star();
console.log(typeof p);

Object related methods

Object.getPrototypeOf()

Object.getPrototypeOfThe method returns the prototype of the parameter object. This is the standard way to obtain a prototype object.

var star = function(){
    
    
    this.name = 'xxxx',
    this.age = 'xx',
    this.sex = 'x',
    this.fun = function(){
    
    
        alert('xxxx');
    }
};

var p = new star();
Object.getPrototypeOf(p) === star.prototype //true

Object.setPrototypeOf()

Object.setPrototypeOf() Static methods can set the prototype (ie, internal properties) of a specified object to another object or null.

const obj = {
    
    };
const parent = {
    
     foo: 'bar' };

console.log(obj.foo);
// Expected output: undefined

Object.setPrototypeOf(obj, parent);

console.log(obj.foo);
// Expected output: "bar"

Object.create()

Object.create()Static methods use an existing object as a prototype to create a new object

const person = {
    
    
  isHuman: false,
  printIntroduction: function() {
    
    
    console.log(`My name is ${
      
      this.name}. Am I human? ${
      
      this.isHuman}`);
  }
};

const me = Object.create(person);

me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // Inherited properties can be overwritten

me.printIntroduction();
// Expected output: "My name is Matthew. Am I human? true"

Object.prototype.isPrototypeOf()

The method of the instance object isPrototypeOfis used to determine whether the object is the prototype of the parameter object.

var o1 = {
    
    };
var o2 = Object.create(o1);
var o3 = Object.create(o2);

// o2 --> o1 
// 03 --> o2 --> o1 
o2.isPrototypeOf(o3) // true
o1.isPrototypeOf(o3) // true
// o1和o2都是o3的原型

Object.prototype.__proto__

function Circle() {
    
    }
const shape = {
    
    };
const circle = new Circle();

// 设置该对象的原型
// 已弃用。这里只是举个例子,请不要在生产环境中这样做。
shape.__proto__ = circle;

// 判断该对象的原型链引用是否属于 circle
console.log(shape.__proto__ === circle); // true

Get comparison of prototype object methods

As mentioned before, __proto__properties point to the prototype object of the current object, which is the constructor's prototypeproperty.

var obj = new Object();

obj.__proto__ === Object.prototype
// true
obj.__proto__ === obj.constructor.prototype
// true

The above code first creates a new object obj, and its __proto__properties point to the properties of the constructor ( Objector obj.constructor) prototype.

Therefore, objthere are three ways to obtain the prototype object of an instance object.

  • obj.__proto__
  • obj.constructor.prototype
  • Object.getPrototypeOf(obj)

Among the above three methods, the first two are not very reliable. __proto__Attributes only need to be deployed in browsers, and do not need to be deployed in other environments. When obj.constructor.prototypemanually changing the prototype object, it may fail.

var P = function () {
    
    };
var p = new P();

var C = function () {
    
    };
C.prototype = p;
var c = new C();

c.constructor.prototype === p // false

In the above code, the prototype object of the constructor Cis changed p, but the instance object c.constructor.prototypedoes not point to it p. Therefore, when changing the prototype object, you generally need to set constructorthe properties at the same time.

C.prototype = p;
C.prototype.constructor = C;

var c = new C();
c.constructor.prototype === p // true

Therefore, it is recommended to use the third Object.getPrototypeOfmethod to obtain the prototype object.

Object.getOwnPropertyNames()

Object.getOwnPropertyNames()The static method returns an array containing all the own properties in the given object (including non-enumerable properties, but not properties using symbol values ​​as names).

const object1 = {
    
    
  a: 1,
  b: 2,
  c: 3
};

console.log(Object.getOwnPropertyNames(object1));
// Expected output: Array ["a", "b", "c"]

Object.prototype.hasOwnProperty()

hasOwnProperty() method returns a Boolean value indicating whether the object has the specified attribute in its own properties (rather than inherited properties).

const object1 = {
    
    };
object1.property1 = 42;

console.log(object1.hasOwnProperty('property1'));
// Expected output: true

console.log(object1.hasOwnProperty('toString'));
// Expected output: false

console.log(object1.hasOwnProperty('hasOwnProperty'));
// Expected output: false

this keyword

Scope

There are three types of scopes in JavaScript:

  • Global scope: the default scope in which all code is run in script mode
  • Module scope: The scope in which code is run in module mode
  • Function scope: the scope created by a function
  • Block-level scope: A scope created with a pair of curly braces (a code blocklet ) (variables declared with or constbelong to additional scopes)

Method to bind this

Function.prototype.call()

call()A method calls a function with a specified thisvalue and one or more arguments given individually.

As a function instance callmethod, you can specify thisthe pointer inside the function (that is, the scope in which the function is executed), and then call the function in the specified scope.

var obj = {
    
    };

var f = function () {
    
    
  return this;
};

f() === window // true
f.call(obj) === obj // true

In the above code, fwhen the global environment runs the function, thisit points to the global environment (the browser is windowthe object); callthe method can change thisthe pointer, specify thisthe pointer to the object obj, and then objrun the function in the scope of the object f.

callThe method parameter should be an object. If the parameters are empty, nulland undefined, the global object is passed in by default.

var n = 123;
var obj = {
    
     n: 456 };

function a() {
    
    
  console.log(this.n);
}

a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456

In the above code, if the keyword ain the function points to the global object, the return result is . If you use the method to point the keyword to the object, the return result is . It can be seen that if the method has no parameters, or the parameters are or , it is equivalent to pointing to the global object.this123callthisobj456callnullundefined

If callthe parameter of the method is a primitive value, then the primitive value will be automatically converted into the corresponding packaging object and then passed into callthe method.

var f = function () {
    
    
  return this;
};

f.call(5)
// Number {[[PrimitiveValue]]: 5}

In the above code, callthe parameter 5is not an object, and will be automatically converted into a wrapping object ( Numberan instance) and bound finternally this.

callMethods can also accept multiple parameters.

func.call(thisValue, arg1, arg2, ...)

callThe first parameter is thisthe object to be pointed to, and the subsequent parameters are the parameters required when the function is called.

function add(a, b) {
    
    
  return a + b;
}

add.call(this, 1, 2) // 3

In the above code, callthe method specifies the binding current environment (object) addinside the function this, and the parameters are 1and 2, so addit is obtained after the function is run 3.

callOne application of methods is to call native methods of an object.

var obj = {
    
    };
obj.hasOwnProperty('toString') // false

// 覆盖掉继承的 hasOwnProperty 方法
obj.hasOwnProperty = function () {
    
    
  return true;
};
obj.hasOwnProperty('toString') // true

Object.prototype.hasOwnProperty.call(obj, 'toString') // false

The above code hasOwnPropertyis obja method inherited by the object. If this method is overridden, the correct result will not be obtained. callThe method can solve this problem. It hasOwnPropertyputs the original definition of the method objon the object for execution, so that whether objthere is a method with the same name or not, it will not affect the result.

Function.prototype.apply()

applyThe function of the method callis similar to that of the method. It also changes thisthe pointer and then calls the function. The only difference is that it receives an array as a parameter when the function is executed, and the format is as follows.

func.apply(thisValue, [arg1, arg2, ...])

applyThe first parameter of the method is also thisthe object to be pointed to. If set to nullor undefined, it is equivalent to specifying the global object. The second parameter is an array, and all members of the array are passed as parameters to the original function. The parameters of the original function callmust be added one by one in the method, but in applythe method, they must be added in the form of an array.

function f(x, y){
    
    
  console.log(x + y);
}

f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2

In the above code, fthe function originally accepted two parameters. applyAfter using the method, it can accept an array as a parameter.

Function.prototype.bind()

bind()Methods are used to bind the function body thisto an object and then return a new function.

var d = new Date();
d.getTime() // 1481869925657

var print = d.getTime;
print() // Uncaught TypeError: this is not a Date object.

In the above code, we d.getTime()assign the method to the variable print, and then print()an error is reported when calling. This is because the instance of the bound object getTime()inside the method no longer points to the instance of the object after it is assigned to the variable .thisDateprintthisDate

bind()method can solve this problem.

var print = d.getTime.bind(d);
print() // 1481869925657

In the above code, bind()the method binds getTime()the method internally thisto dthe object. At this time, the method can be safely assigned to other variables.

bindThe parameter of the method is thisthe object to be bound. Here is a clearer example.

var counter = {
    
    
  count: 0,
  inc: function () {
    
    
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

In the above code, counter.inc()the method is assigned to the variable func. At this time, you must use bind()a method to bind inc()the internal one thisto counter, otherwise an error will occur.

thisBinding to other objects is also possible.

var counter = {
    
    
  count: 0,
  inc: function () {
    
    
    this.count++;
  }
};

var obj = {
    
    
  count: 100
};
var func = counter.inc.bind(obj);
func();
obj.count // 101

In the above code, bind()the method binds inc()the method inside the method thisto objthe object. As a result, after calling the function, the internal attributes funcare incremented .objcount

bind()It can also accept more parameters and bind these parameters to the parameters of the original function.

var add = function (x, y) {
    
    
  return x * this.m + y * this.n;
}

var obj = {
    
    
  m: 2,
  n: 2
};

var newAdd = add.bind(obj, 5);
newAdd(5) // 20

In the above code, bind()in addition to binding thisthe object, the method also binds add()the first parameter of the function to and then returns a new function . This function only needs to accept one more parameter to run.x5newAdd()y

If bind()the first parameter of the method is nullor undefined, equals will be thisbound to the global object and the function thiswill point to the top-level object when running (for browsers window).

function add(x, y) {
    
    
  return x + y;
}

var plus5 = add.bind(null, 5);
plus5(10) // 15

In the above code, add()there is no function inside the function. The main purpose of thisusing the method is to bind parameters . Every time you run a new function in the future , you only need to provide another parameter . And because there is no one internally , the first parameter is , but if it is another object here, it will have no effect.bind()xplus5()yadd()thisbind()null

prototype property

prototype chain

In JavaScript, all objects have their own prototype object (prototype). On the one hand, any object can serve as the prototype of other objects; on the other hand, since the prototype object is also an object, it also has its own prototype. Therefore, a "prototype chain" will be formed: object to prototype, then to prototype's prototype...

If you go back layer by layer, the prototypes of all objects can eventually be traced back to Object.prototypethe properties Objectof the constructor prototype. Object.prototypeThat is, properties that all objects inherit . This is why all objects have valueOfand toStringmethods, because this is Object.prototypeinherited from.

Introduction to prototype property

In Javascript, every function has a prototypeproperty pointing to an object

function f() {
    
    };
typeof f.prototype //=>'object'

// 函数f默认具有prototype属性,指向一个对象。

For the constructor, when an instance is generated, this property will automatically become the prototype of the instance object.

function Anmal(name){
    
    
    this.name = name;
};

var name1 = new Anmal('大猫');
var name2 = new Anmal('小猫');

// 由上述代码可以知道name1,name2的原型对象是Anmal

name1.prototype.color = 'white';
上面代码中,`name1.prototype`对象上面定义了一个`color`属性,这个属性将可以在所有`name1`实例对象上面调用。

constructor property

describe

Any object other than a prototype object will have nulla[[Prototype]] property on it constructor. Objects created using literals will also have a constructorproperty pointing to the object's constructor type, for example, objects created with array literals Arrayand ordinary objects created with object literals .

For example:

function Tree(name) {
    
    
  this.name = name;
}

const theTree = new Tree("Redwood");
console.log(`theTree.constructor 是 ${
      
      theTree.constructor}`);

// 输出为
theTree.constructor 是 function Tree(name) {
    
    
  this.name = name;
}

___proto___ attribute

describe

__proto__The getter function exposes the internal [[Prototype]]value of an object. For objects created using object literals, this value is Object.prototype. For objects created using array literals, this value is Array.prototype. For functions, the value is Function.prototype. You can learn more about prototype chains in Inheritance and Prototype Chains .

__proto__The setter allows modification of an object [[Prototype]]. The provided value must be an object or null. Providing any other value has no effect.

Unlike Object.getPrototypeOf()and Object.setPrototypeOf(), they always Objectexist as static properties of and always reflect [[Prototype]]internal properties of . __proto__Properties do not always exist as attributes of all objects and therefore cannot be reflected reliably [[Prototype]].

__proto__A property is Object.prototypea simple accessor property consisting of getter and setter functions. If __proto__the property is eventually queried when accessing it Object.prototype, the property will be found, but if there is no query Object.prototype, the property will not be found. If other attributes Object.prototypeare found before querying , the attributes on will be overwritten .__proto__Object.prototype__proto__

nullPrototype objects do not inherit any properties from Object.prototype, including __proto__accessor properties. So if you try to read on such an object , the value will always be __proto__no matter what the object's actual is , and any assignment to will create a new property named instead of setting the object's prototype. Additionally, it can be redefined as an own property of any object instance without triggering the setter. In this case, there will no longer be an accessor for . Therefore, to set and get objects , always use and .[[Prototype]]undefined__proto____proto____proto__Object.defineProperty()__proto__[[Prototype]][[Prototype]]Object.getPrototypeOf()Object.setPrototypeOf()

const ShapeA = function () {
    
    };
const ShapeB = {
    
    
  a() {
    
    
    console.log("aaa");
  },
};

ShapeA.prototype.__proto__ = ShapeB;
console.log(ShapeA.prototype.__proto__); // { a: [Function: a] }

const shapeA = new ShapeA();
shapeA.a(); // aaa
console.log(ShapeA.prototype === shapeA.__proto__); // true

Guess you like

Origin blog.csdn.net/bo1029/article/details/131970975