js new关键字的使用以及原型链

2020-11-16  本文已影响0人  变量只提升声明不提升赋值

首先上代码

 function fs () {
    this.name = '哈哈'
   fs.say = function () {
     console.log('i am ' + this.name)
   }
 }
 var cc = new fs()
    console.log(cc)
    console.log(cc.p)
    cc.say()
image.png

这里我们首先创建了一个构造函数,配合上new关键字,看看new到底做了啥

 function fs () {
   //1.创建一个新对象,赋予this,这一步是隐性的,
   // let this = {};
   //2.给this指向的对象赋予构造属性
    this.name = '哈哈'
   fs.say = function () {
     console.log('i am ' + this.name)
   }
   //3.如果没有手动返回对象,则默认返回this指向的这个对象,也是隐性的
   // return this;
 }

接下来再解释一下上面执行结果是为什么

    console.log(cc) //输出cc对象
    console.log(cc.p) //cc并没有p这个属性所以undefined
    cc.say() //cc也没有say这个方法所以报错,say不是个函数

至于为什么,我们打开cc这个对象看看

image.png
可以看到,cc这个对象除了有一个name属性之外,他的原型对象上并没有任何其他东西了,我们都知道,js在访问一个对象的属性或者方法的时候,会沿着原型链一层一层的去找,也就是proto这个对象,如果这个对象身上没有,又会在proto对象的proto属性身上去找,一直到最大的boss object身上,如果都没找到就会返回null,返回null的原因也很简单,因为大boss的原型指向的就是null

这里就涉及到了原型链和原型对象,原型对象也分为显式原型对象和隐式原型对象

proto就是隐式原型对象 而还有一个prototype则是显式原型对象

在js中万物皆对象,函数其实也是个对象,只不过他比较特别,他不但有proto这个属性,他还有一个prototype属性

一个对象的proto其实是指向他的构造函数的prototype原型的 接下来再看一个例子

function fs () {}
 fs.prototype.p = 1
 fs.prototype.say = function(){
   console.log('i am' + this.p)
 }
 var cc = new fs()
 console.log(cc)
 console.log(cc.p)
 cc.say()
image.png

这次我们在构造函数的原型对象prototype上添加了一个属性p=1 say=一个函数
这一次我们在打开cc这个对象的proto属性可以看到,诶!有p 还有say这个函数
所以打印的话也没有问题,正确的输出了

image.png
至于这个constructor暂时还没有搞明白是个咋回事,
cc的原型链是 proto --> fs.prototype --> object.proto
上一篇下一篇

猜你喜欢

热点阅读