js原型链解析

原型链原理

javaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾(摘抄自菜鸟教程prototype原型对象)

案例一

在B站看到了一个很好的JavaScript原型链的视频,看完后把里面的案例改了改写了下来,里面加了一些自己的见解和实践步骤

B站视频地址:https://www.bilibili.com/video/BV1N7411k7D2?from=search&seid=10380415292130567182

//supermarket 超级市场
function supermarket(){};
supermarket.prototype.goods = "洗衣机";

//shop 商店
function shop(){};

shop原型链继承supermarket原型链,也可以理解把商店(shop)理解为分经销商,把超级市场(supermarket)理解为总经销商,分经销商所有的货都是从总经销商那里拿到的

shop.prototype = new supermarket();

这个时候有一个人,需要洗衣机洗衣服,但是自己家里没有洗衣机,这个时候他就去商店买洗衣机,结果到了商店,老板告诉他,他们店里卖的没有洗衣机,但是告诉这个人超级市场卖的有,于是这个人去了超级市场终于买到了洗衣机

//person 人
var person = new shop();

console.log(person.goods); //洗衣机

总结:上面的案例就和原型链原理是一样的,一环扣一环,当我们调用person.goods的时候,实例会查看shop原型对象有没有goods这属性,查看shop原型对象后发现没有goods这个属性,但是shop原型对象成为了supermarket的实例,因此就可以继续往上找也就是supermarket原型对象,当找到supermarket原型对象后查看后发现supermarket原型对象刚好设置了goods这个属性,然后就可以返回supermarket原型对象这个结果了。

但是如果这样写shop.prototype.goods = new supermarket();

console.log(person.goods); //就会打印supermarket

或者 shop.prototype.goods = "哈哈"

console.log(person.goods); //哈哈

这也依了原型链的依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾(到达原型链末尾后如果没有找到匹配的属性则会输出undefined)

案例二

下面是我根据js基础数据类型和引用数据类型的层级关系写的一个案例

js基本数据类型(按值访问):String、number、Boolean 、null(空)、undefined(未定义)
js引用数据类型(按引用访问):Array、function、object
按值访问和按引用访问 参考:https://blog.csdn.net/u014682746/article/details/104991631

{}和[]的区别 {}为js对象、[]为Array数组

这里的声明foo没有用到,声明foo主要为了{}和[]区别,因为我发现很多人也喜欢把foo这种对象也称之为数组

虽然{}和[]同时用的时候确实可以称之为对象数组(如下图struct对象),但是从原则来说struct的类型是属于js对象的 typeof struct 输出 object

var foo = {}; //js对象 object类型 typeof foo 输出 object ; foo instance Array 输出为 false(假)
var arr = []; //Array数组 也属于object类型 typeof arr 输出 object; foo instance Array 输出为 true(真)
var F = function(){}; //function函数 属于function函数和object对象 typeof F 输出 function

Object.prototype.one = function (){return 'Object对象'}; //创建object原型链
Function.prototype.two = function (){return 'function函数'}; //创建function原型链

new一个新对象(实例化对象为f,object类型)
function引用数据类型变为object引用数据类型(因为F为function引用数据类型,但是f经过new实例后变为了object引用数据类型)
提示:不管是数组类型(Array)、字符串类型(String)、数字类型(number)、null、Undefined、布尔类型(Boolean),new实例后接收的name都是object类型
var f = new F() ;

//arr Array数组;F function函数;f object对象 

console.log(arr.one) //返回object原型链,打印function(){return 'Object对象'}
console.log(arr.two) //Array数组 打印undefined
console.log(F.one) //返回object原型链,打印function(){return 'Object对象'}
console.log(F.two) //返回Function原型链,打印function(){return 'function函数'}
console.log(f.one) //返回object原型链,打印function(){return 'Object对象'}
console.log(f.two) //object对象 打印undefined

Array.prototype.one = function (){return 'Array数组'}; //创建Array原型链

在这里arr.one 之所以没有在输出object的原型链 是因为arr是属于Array数组 在Array原型链没有创建的前,arr数组在层层向上搜索的过程搜不到arr的上级Array原型,才会去找Array原型的上级object原型,但是如果foo数组找到了Array原型后就会直接引用Array声明的原型对象停止继续向上寻找

console.log(arr.one) //返回Array原型链,打印function(){return 'Array数组'}

还有一些知识点,没填加进去,最近会慢慢完善(不想告诉你们其实是要下班了)

原文地址:https://www.cnblogs.com/cjh-strive/p/14597991.html