如何彻底理解Javascript中this指向、ES6中class、原型链以及ES6中class之间的联系?

作为一名工作两年多的前端开发者来说,原型链一直是困扰我的问题。

很震惊吧,作为前端怎么连这么基础的问题都不清楚,怎么找到工作的?

其实一点也不奇怪!

正常工作中前端起到的作用无外乎“搬砖”,需要组件了很少自己写,基本都是“问度娘”。

(大神就算了,当我没说。)

闲来无事,查了很多资料和文档,终于理清了他们之间的关系,特此记录一下。

这里总结一下路线:

  1. this指向
  2. 原型链
  3. class类和原型链关系

一、this指向问题

this指向的永远是调用它的对象。

function a(){
    var user = "码农无码";
    console.log(this.user); //undefined
    console.log(this); //Window
}
a(); // 实际上可以理解为:a() === window.a()

从代码可以看出a方法是被window直接调用的,因此,this指向的是window。


var o = {
    user:"码农无码",
    fn:function(){
        console.log(this.user); // 码农无码
    }
}
window.o.fn();
// 通过window -->  o --> fn调用,却输出了o的user属性值,为什么呢?

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //12
        }
    }
}
o.b.fn();
// 这里多级嵌套,只输出了a = 12,而不是a=10

如果这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。


var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();

为什么呢?是不是很奇怪?

切记:this永远指向的是最后调用它的对象

你品,你细品!

j被赋值的时候,方法fn并没有被调用,直接调用者为:window.j(),因此this指向的是window而不是b。

到这里,基本this的指向问题就基本理解差不多了。

 

二、原型链的理解

原型链最重要的三个属性:prototype、__proto__、constructor

每个构造方法都具备prototype属性,这个属性指向一个对象。

function Person() {

}
// 虽然写在注释里面,但是需要注意的是
// prototype 是函数才会有的属性
Person.prototype.name = "Kevin";
var person1 = new Person();
var person2 = new Person();

console.log(person1.name) // Kevin
console.log(person2.name) // Kevin


每一个JavaScript对象(除了null)都具有的一个属性,叫__proto__,这个属性会指向该对象的原型,即作为实例对象和实例原型的之间的链接桥梁。

function Person() {

}

var person = new Person();
console.log(person.__proto__ === Person.prototype); //true;

function Person() {

}
console.log(Person === Person.prototype.constructor); // true

function Person() {

}

var person = new Person();

console.log(person.__proto__ == Person.prototype) // true
console.log(Person.prototype.constructor == Person) // true
// 顺便学习一个ES5的方法,可以获得对象的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

1.声明了构造函数 Person;
2.使用new操作符调用 Person 实例化了一个person 对象;
3.判断实例化对象通过__proto__是否指向实例原型;
4.判断实例原型通过constructor是否能找到对应的构造函数;
5.使用Object.getPrototypeOf方法传入一个对象 找到对应的原型对象;

三、ES6中class和原型链之间的关系

class User{  

  constructor(){     

   console.log('默认调用');  

  }  

  eat(){    

    console.log('eat方法');  

  }

}
var user = new User();//默认调用

user.eat()//eat方法

等同于:

function User() {}

User.prototype.eat = function () {}

因此可以总结为:

类:User === 构造函数User.protoType(实例原型)

类User的constructor指向构造函数User


简单总结下,如有问题,请指出!

后期有时间继续完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值