写在前边的话
其实在写这个标题之前,想搞清楚的问题完全不是这个;但是在原本的问题上,好像钻了牛角尖,愈发的出不来,各路资料查来阅去,离出发点越来越远;以至于现在完全想不起最初的问题是啥了,看历史记录大概是object之类的;不过对于原型链的理解有了加深,索性就写一篇相关的帖子交作业好了。以下只是对我来说更好的理解,分享下-可能中间某些环节‘每有会意遍欣然忘食’,本着‘尽信书不如无书’哪里不对欢迎斧正;
什么是原型链
JavaScript 只有一种结构:对象。每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
这段描述是MDN我直接照搬过来的,至于有多少人能读一次就通透理解我很怀疑;我自己来说,学中文出身,淘宝9.9课程自学前端,工作3年甚至从来没用到过,更别提搞懂这大段的文本描述了。
prototype
Object.prototype 属性表示 Object 的原型对象。prototype属性使我们有能力向Object添加属性和方法。通过MDN了解到ES的标准名称应该是[[prototype]]
还拿之前的例子来说
function Cat(name, sex, age) {
this.name = name;
this.sex = sex;
this.age = age;
}
Cat.prototype.leg = 4;
Cat.prototype.sayName = function () {
console.log(this.name);
}
console.dir(Cat)
/*
ƒ Cat(name, sex, age)
arguments: null
caller: null
length: 3
name: "Cat"
prototype: {leg: 4, sayName: ƒ, constructor: ƒ}
__proto__: ƒ ()
[[FunctionLocation]]: html.html:20
[[Scopes]]: Scopes[1]
*/
_ proto_
Object.prototype 的 proto 属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]] (一个对象或 null)。proto是浏览器对于es的实现。接上边
var dahuang = new Cat("dahuang", "boy", 8);
console.dir(dahuang)
Cat
age: 8
name: "dahuang"
sex: "boy"
__proto__:
leg: 4
sayName: ƒ ()
constructor: ƒ Cat(name, sex, age)
__proto__: Object
这里我们让大黄高喊出他的名字;
dahuang.sayName()
//dahuang
可是大黄是兔子,明明不会说话,最多也就汪一声,这个‘dahuang’是哪来的;
js引擎在看到dahuang上没有sayName属性,下一步在proto上开始查找,然而在这里破案了,发现了大黄开口的真相;
我们再次让大黄做点上难度的
dahuang.toString()
//"[object Object]"
这回别说dahuang上没有了就连proto上也没,依次猜想,这次应该是在找proto上的proto
由此可见js引擎在寻找属性时会一直dahuang.__ proto__.__ proto__.__ proto__找下去。
再次验证一下,顺便让大黄亮点绝活;
dahuang.howyougan()
//error not a function
果然大黄并不会庐山升龙霸;既然说是验证,这次这么玩,既然都是对象,那不给cat的原型上加,直接把秘籍传给object;
Object.prototype.howyougan = function(){
console.log('大黄使出了:')
console.log('庐山升龙霸霸霸霸霸霸')
console.log('效果拔群')
}
到这里这一连串的查找链路其实就是经常说到的,原型链
思考
javascript最初设计也只是为了迎合市场才加入面向对象,相关的规范并不完整,或者有各种漏洞,而新出的class也不过是语法糖本质上似乎还是这套东西;‘__ proto__的使用是有争议的’,而现在各单位面试仍然需要熟练掌握,在学习中是否应该把中心放到他的替代品上。
参考博文:
帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
JS 中 proto 和 prototype 存在的意义是什么?