JavaScript最容易confusingly-name parts


Important: The prototype property is one of the most confusingly-named parts of JavaScript — you might think that it points to the prototype object of the current object, but it doesn't (that's an internal object that can be accessed by __proto__, remember?). prototype instead is a property containing an object on which you define members that you want to be inherited.

原型属性, 不是对象的原型对象, 它是对象内部属性,can be accessed by __proto__
prototype 是一个属性,这个属性包含一个对象, 你定义新对象时候,prototype里面的对象会被继承。



1. Object.create()
创建一个新对象, 从一个原型对象里面创建新对象。,这个对象被当做是原型对象。
let p2 = Object.create(p1) ,  p1被当做是p2的原型对象。 p2.__proto__  ===  p1


2. 构造函数原型
每个构造函数function都有prototype属性
prototype属性的value是一个对象, 这个对象包含一个constructor 属性,
constructor属性指向原始的constructor function.

属性定义在  构造函数/对象(通常称为构造函数,他也是对象) 的原型属性, 那通过构造函数创建的实例对象都可以用构造函数的prototype.property(好绕口)。
通过构造函数   创建 的实例,可以调用构造函数里的原型属性。

person1.constructor
person2.constructor

person1.construnctor   === Person()  构造函数

let person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);

This works well. You won't need to use it often, but it can be really useful when you want to create a new instance and don't have a reference to the original constructor easily available for some reason.

person1.constructor.name


Note: The value of constructor.name can change (due to prototypical inheritance, binding, preprocessors, transpilers, etc.). Therefore, for more complex examples, you'll want to use the instanceof operator instead.

修改原型-Modifying prototypes

修改一个构造函数的prototype

增加一个构造函数的原型属性的方法
Person.prototype.farewell = function() {
  alert(this.name.first + ' has left the building. Bye for now!');
};

In the above example, performing delete person1.__proto__.farewell or delete Person.prototype.farewell would remove the farewell() method from all Person instances.

In order to mitigate this issue, you could use Object.defineProperty() instead.

Person.prototype.fullName = this.name.first + ' ' + this.name.last;

However, this doesn't work. That's because this will be referencing the global scope in this case, not the function scope. Calling this property would return undefined. This worked fine on the method we defined earlier in the prototype because it is sitting inside a function scope, which will be transferred successfully to the object instance scope. So you might define constant properties on the prototype (i.e. ones that never need to change), but generally it works better to define properties inside the constructor.

Person.prototype.fullName = function(first, last) {console.log(first + '   ' + last);}

person1.fullName(person1.name.first, person1.name.last)




In fact, a fairly common pattern for more object definitions is to define the properties inside the constructor, and the methods on the prototype. This makes the code easier to read, as the constructor only contains the property definitions, and the methods are split off into separate blocks. For example:

// Constructor with property definitions

function Test(a, b, c, d) {
  // property definitions
}

// First method definition

Test.prototype.x = function() { ... };

// Second method definition

Test.prototype.y = function() { ... };

// etc.


阅读量: 406
发布于:
修改于: