关于javascript的原型和原型链,看我就够了

Posted 前端陌上寒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于javascript的原型和原型链,看我就够了相关的知识,希望对你有一定的参考价值。

温故

我们先回顾一下前两天讨论的内容

创建对象的三种方式

  • 通过对象直接量

  • 通过new创建对象

  • 通过Object.create()

js中对象分为两种

  • 函数对象

  • 普通对象

原型对象prototype

  • 每一个函数对象都有一个prototype属性,但是普通对象是没有的;

  • 普通对象都是通过函数创建的

在 ECMAScript 核心所定义的全部属性中,最耐人寻味的就要数 prototype 属性了。对于 ECMAScript 中的引用类型而言,prototype 是保存着它们所有实例方法的真正所在。换句话所说,诸如 toString()和 valuseOf() 等方法实际上都保存在 prototype 名下,只不过是通过各自对象的实例访问罢了。----《javascript 高级程序设计》

构造函数constructor

function Foo(name{
    this.name = name;
}
var foo = new Foo('陌上寒');
 console.log(Foo.prototype.constructor===Foo)//true
 console.log(foo.constructor===Foo);//true

原型对象有一个constructor属性,指向该原型对象对应的构造函数
foo 为什么有 constructor 属性?那是因为 foo 是 Foo 的实例。
那 Foo.prototype 为什么有 constructor 属性??同理, Foo.prototype Foo 的实例。
也就是在 Foo 创建的时候,创建了一个它的实例对象并赋值给它的 prototype

隐式原型__proto__

在Firefox、Safari 和 Chrome 的每个对象上都有这个__proto__,属性 ,而在其他浏览器中是完全不可见的为了确保浏览器兼容性问题,不要直接使用 proto 属性)

// 普通对象的\__proto\__指向当前函数对象的原型,
console.log('陌上寒'.__proto__===String.prototype);//true
//原型对象(也属于普通对象)的__proto__指向当前函数对象的原型
console.log(String.prototype.__proto__===Object.prototype);//true
//内置函数对象的\__proto\__指向的都是ƒ () { [native code] }
console.log(Object.__proto__);//ƒ () { [native code] }
//Object的原型对象的\__proto\__为null
console.log(Object.prototype.__proto__)//null
  • 普通对象的__proto__指向当前函数对象的原型,

  • 原型对象(也属于普通对象)的__proto__指向当前函数对象的原型

  • 内置函数对象的__proto__指向的都是ƒ () { [native code] }

  • 所有对象(除了Object.prototype)都存在__proto__

  • Object的原型对象的__proto__为null
    好好消化上面的知识点,有助于我么讨论新的内容==>原型链

知新

原型链

  • 原型对象prototype

  • 构造函数constructor

  • 隐式原型__proto__
    通过三者之间的联系,形成了原型链
    继续看一下我门昨天讨论过的代码

console.log('陌上寒'.__proto__===String.prototype);//true
console.log(String.prototype.__proto__===Object.prototype);//true
//等量代换,得出以下结论
console.log('陌上寒'.__proto__.__proto__===Object.prototype);//true

我们刚才说过,普通对象的__proto__指向当前函数对象的原型
我们刚才还说过,普通对象都是通过函数创建的
根据以上两个结论我们分析一下上面的代码
‘陌上寒’是字符串类型,’陌上寒’的构造函数是String(), 所以’陌上寒’的proto指向String的原型
String是js的内置构造函数,内置构造函数继承自Object
String的原型对象String.prototype也是一个普通对象,它的__proto__指向Object的原型,即Object.prototype
所以

console.log('陌上寒'.__proto__.__proto__===Object.prototype);//true

这就是原型链
我们继续品读以下代码

//我们创建一个构造函数Foo(要记得,构造函数命名,首字母要大写)
function Foo({}
//通过我们自定义的构造函数。通过new操作符,我们实例化出来一个对象foo
const foo = new Foo()
//对象的__proto__指向当前函数对象(foo是同构Foo实例化出来的,所以foo的函数对象是Foo)的原型
console.log(foo.__proto__===Foo.prototype);
//原型对象也存在__proto__,指向该原型对象(Foo.prototype)所对应的函数对象(Object)的原型(好像有点绕,看代码就没那么绕了)
console.log(Foo.prototype.__proto__===Object.prototype);//true
//上面的如果懂了,这行代码就简单了,一个数学的等量代换,就得出了结论
console.log(foo.__proto__.__proto__===Object.prototype);//true
console.log('---我是分割线----');
//我们通过字面量创建了一个对象,等同于 const obj = new Object()
const obj = {}
//obj 是通过内置构造函数Object创建的,所以,obj的__proto__指向它的函数对象(Object)的原型(prototype)即:Object.prototype
console.log(obj.__proto__===Object.prototype);//true
console.log('---我是分割线----');//true
//创建一个对象b
const b = {}
//我们之前说过创建对象有三种方式,我们使用第三种方式创建一个对象b1,对象b1继承自对象b,也就是说,对象b是对象b1的__proto__
const b1 = Object.create(b)
//对象b是对象b1的__proto__
console.log(b1.__proto__===b);//true
//前面已经证实过,b.__proto__==Object.prototype,不再赘述
console.log(b.__proto__==Object.prototype);//true
//等量代换就得出以下结论
console.log(b1.__proto__.__proto__===b.__proto__);//true
console.log(b1.__proto__.__proto__==Object.prototype);//true

我偷了一张图

以上是关于关于javascript的原型和原型链,看我就够了的主要内容,如果未能解决你的问题,请参考以下文章

十大经典排序算法动画与解析,看我就够了!(配代码完全版)

关于mac与windows的文件共享(看我的就够了)

SVNGIT日常看我就够了

十大经典排序算法动画与解析,看我就够了!(配代码完全版)

小伙,多线程(GCD)看我就够了,骗你没好处!

Vue中的组件,看我就够了