1.原型
- JavaScript对象是属性名与属性值的集合
- 每一个函数都有一个原型对象
- 构造函数举例:
functionNinja(){}//定义一个空函数什么也不做
Ninja.prototype.swingSword = function(){//每个函数都具有内置原型对象,我们可以对其自由更改
return true;
};
const ninja1 = Ninja();//作为调用函数,没有返回任何值,此时ninja1的值是undefined
const ninja2 = new Ninja();//作为构造函数调用Ninja,ninja2不仅创建了新的实例,并且该实例具有原型上的方法swingSword()
ninja2的原型被设置为构造函数的原型的引用,通过这种方法,ninja2调用方法swingSword,将查找该方法委托到Ninja的原型对象上,Ninja创建出来的对象都可以访问swingSword方法,这样就实现了继承。
- 可以通过Object.setPrototypeOf方法定义对象的原型
2.继承
函数原型对象具有constructor属性,该属性指向函数本身,该函数创建的全部对象均访问该属性,construtor指向实例的构造函数,可以验证实例原始类型(与instanceof很像),也可以直接构造实例。
const ninja = new Ninja.constructor()
- 继承的原生实现:如果我们希望Ninja构造函数的所有实例都可以继承Person构造函数的属性,那么将Ninja构造函数的原型设置为Person类的实例。
function Person(){}
Person.prototype.dance = function(){};
function.Ninja(){}
Ninja.prototype = new Person();
Object.defineProperty(Ninja.prototype,"constructor",{
Enumerable:false,
Value:Ninja,
Writable:true
});
Var ninja = new Ninja();
//Ninja继承了Person的方法,并且ninja实例可以向上查找
}
- 在JavaScript中,原型具有属性(configurable,enumerable,writable),这些可以通过内置的Object.defineProperty方法进行定义。
- JavaScript ES6引入关键字class,使得我们可以更方便地实现模拟类,不过在底层仍是原型实现的
使用extends可以更优雅的实现继承