Function的prototype 原型链 static详解
此前我有看过网上很多的关于该知识点的详解,很多文章都非常难懂,且篇幅较长,可能是以学习研究为目的。这篇文章结合了理论与实践,希望各位大佬多多批评!
基本介绍
有class类式声明 用于声明对象,在这里我更加偏向于用函数。
Function -> prototype(用于声明公共变量和方法) constructor(指向自身,了解即可);
fObj(函数new 出来的实例) -> __proto __ 或 [[prototype] ] (谷歌) (原型链,与原函数的prototype相等) constructor(原型链中的属性,指向原函数自身)
关于继承:react官网中阐述了继承与组合在框架当中的应用,组合会被使用的更多,所以暂不讨论extents继承。
图示如下
画的较丑^ _ ^
声明一个函数
函数原型相当于一个函数的公共空间,所有new出来的对象都可以使用空间中的属性和方法。实际是将公共方法进行整合,将全局变量变成方法局部变量,用于封装js插件。
//声明原型
function FnC(x, y) {
this.x = x; // this将来会指向 new出来的对象,这里声明原型变量
this.y = y;
//声明原型函数 方式1
this.show1 = function() {
console.log('show1:' + this.x + this.y);
}
}
//声明原型函数 方式2
FnC.prototype.show2 = function(){
//TODO2
}
//声明静态方法 使用的时候可以直接通过方法名去调用
FnC.showS = function() {
console.log('静态方法',this.x + this.y)
}
new 对象
//创建对象
let obj1 = new FnC('a', 'b');
//使用原型方法
obj1.show1();
obj1.show2();
obj1.__proto__.show2();
static
我的理解是,静态方法将是将一些附加旁类的行为挂钩到函数上,方便使用。例如:window对象上的location-document,Math系列的方法random、pow、max等。
//使用例文静态方法 通过函数名调用,切记不能用实例调用
FnC.showS();
扩展1
如何扩展或者在已创建的对象上,添加公共方法呢?对于一些封装好的库,最好不要去改变原文件。
//方式1
//例如:给数组加上自定义的方法,数组对象即Array
Array.prototype.constom1 = function(){
//TODO
}
//自定义函数
FnC.prototype.constom2 = function(){
//TODO
}
//方式2
let obj2 = new FnC('a', 'b'); //创建好了的对象
obj2.__proto__.constom3 = function(){
//TODO
}
//原由:对象的原型链包含或相等于原函数的原型链。
console.log(FnC.prototype === obj1.__proto__); //true
console.log([1,2].__proto__ === ['sdosa'].__proto__); //true 对象的原型链属于同一公共函数的原型
这种方式将公用行为进行抽象共有,对与代码的重构非常有帮助。详见js的设计模式与开发实践一书。
扩展2
两种判断原型是否存在与原型链的方法
// 测试1 判断FnC的原型 是否存在于 obj的原型链中
console.log(FnC.prototype.isPrototypeOf(obj)); false | true
// 测试2 判断FnC的原型 是否存在于 obj的原型链中
console.log(obj instanceof FnC); false | true
constructor指向问题
//函数自身的constructor | new出来对象 __proto__的constructor 都是指向原函数
console.log('constructor',Fnc === FnC.prototype.constructor); //true
console.log('constructor2',FnC === obj.__proto__.constructor); //true