1. 如何通过构造函数模拟对象类,以及如何创建对象实例.
2. 对象如何继承,原型链如何工作,原型机制
当谈到继承时,JavaScript 只有一种结构:对象。
每个对象都拥有一个原型对象, 原型对象以原型为模板,继承原型的方法和属性. 原型对象也可能拥有原型对象,这样依次展开,就形成是我们所说的 原型链 。它解释了为何一个对象会拥有定义在其他对象中的属性和方法。
a. 原型(prototype)是函数的一个隐形属性, 通过例子打印结果如下
function doSomething(){}
doSomething.prototype.foo = "bar";
console.log( doSomething.prototype );
/* 打印结果如下:
{
foo: "bar",
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
*/
通过这个函数实例化一个新对象obj, obj中的解构如下: 变量 + _proto_
function Dosomething(){}
doSomething.prototype.foo = "bar";
var obj = new Dosomething;
obj.name = "bb"
console.log(obj);
/*
*打印结果如下
* name : bb
* __proto__: {
foo: "bar",
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
*/
通过打印结果发现,实例化得到的对象的__proto__值 与 函数的prototype一致
function Dosomething(){}
doSomething.prototype.foo = "bar";
var obj = new Dosomething;
obj.name = "bb"
console.log(obj);
console.log(Dosomething.prototype === obj._proto_) // 打印结果 true
b. 原型对象 _proto_
通过对象可以调用得到的属性或者方法,是在自身原型链上进行层层查找的。
function Person () {
this.name = "xiaoyu";
this.setName = function (n) {
this.name = n;
};
};
Person.prototype.gender = "1";
var p = new Person();
p.age = 18;
console.log(p.name); // xiaoyu //这个是通过实例化得到的,是在P自己的空间里
console.log(p.gender ); // 1 这个是通过原型链查找到的,不在P自己的空间里
console.log(p.setName('bb'));
console.log(Person);
console.log( p);
//
age: 18
name: "bb"
setName: ƒ (n)
__proto__:
gender: "1"
constructor: ƒ Person()
__proto__: Object