1. JS没有类
js更加没有“construction/构造函数”这些概念。在js中,只存在object/对象。我们知道,在java或者c++中,class和instance是两个概念,class相当于一组DNA, instance相当于实体。但在javascript中,没有DNA,没有class,只有对象。
我避免在javascript中使用“继承”这个术语,由于“继承==拷贝”。但在js中本身就没有“继承”这个行为。
js中存在的是原型链 (prototype chain) 和代理 (delegation)。
2. 原型链
在js中,每个object在创建的时候,都会有一个内置的[[Prototype]属性,会去指向另一个对象。
2.1 new
var obj=new Foo();
Object.getPrototypeOf(obj) === Foo.prototype //true.
当我们以new的方式去调用某函数func的时候:
- 函数声明时,js引擎自动生成了一个对象,func.protype,同时这个对象上自动定义了一个属性为.constructor指向该函数(refer back);
- 以new这个函数生成的新对象,其内置属性[Prototype]指向func.prototype.
2.2 Object.create()
var anotherObj={
a:1
}
var someObj=Object.create(anotherObj);
Object.getPrototypeOf(someObj) === anotherObj; //true.
2.3 instanceOf
语法:obj instanceof function
js引擎做的事情,是在以obj为底层对象的原型链上查找,是否存在function.prototype.
2.4 isPrototyeOf
语法:obj1.isPrototypeOf(obj2)
js引擎做的事情,是在以obj2为底层对象的原型链上查找,是否存在obj1.
3. [get] and [set]
我们去读取某个对象属性的时候,触发[get]操作; 我们设置某个对象属性的时候,触发[set]操作。
原型链机制
- 如果我们在对象本身找不到某个属性的时候,会沿着原型链一直查找,直到原型链终止或者找到这个属性。
- 如果我们想要assign对象中某个不存在的属性但是原型链中某个对象存在这个属性的时候。我们要谨慎考虑:1. 如果这个属性是以setter/getter方式定义,那么直接修改的是原型链中对象上的属性;2. 如果这个对象不是setter/getter方式定义,并且是可写的,那么会在原来的底层对象中定义新属性并且赋值;3. 如果如果这个对象不是setter/getter方式定义,并且不可写,严格模式下报错,非严格模式会忽略这一语句。
4. delegation的一段简单code
function Foo(name){
this.name=name;
}
Foo.prototype.myname=function(){
return this.name;
}
function Bar(name,label){
Foo.call(this,name);
this.label=label;
}
Bar.prototype=Object.create(Foo.prototype); //*
var myObj=new Bar('a','label a');
console.log(myObj.myname()); //'a'