一、call() 方法的使用
- call():调用这个函数,并且修改函数运行时的 this 指向。
语法:fun.call(thisArg, arg1, arg2, ...)
- this.Arg:当前调用函数 this 的指向对象
- arg1, arg2:传递的其他参数
//ES5 直接调用 function fn(){ console.log('I want to eat.') console.log(this) //this 指向 window } fn()
// ES6 call() 方法 function fn(){ console.log('I want to eat.') console.log(this) } fn.call()
//ES6 的 call() // call 方法 function fn(x, y){ console.log('I want to eat.') console.log(this) //this 指向 o 这个对象 console.log(x + y) } let o = { name: '不易' } // 2.call() 可以改变 fn 的 this 指向 此时这个函数的 this 就指向了o 这个对象 fn.call(o, 1 , 2)
二、借用构造函数继承父类型属性
- 核心原理:通过 call() 把父类型的 this 指向子类型的 this,这样就可以实现子类型继承父类型的属性。
// 1.父构造函数 function Father(uname, age){ // this 指向父构造函数的对象实例 this.uname = uname this.age = age } // 2.子构造函数 function Son(uname, age, score){ // this 指向子构造函数的对象实例 Father.call(this, uname, age) //把父亲的 this 改成 孩子的 this this.score = score } let son = new Son('张三', 18, 100) console.log(son)
三、利用原型对象继承方法
// 1.父构造函数 function Father(uname, age){ // this 指向父构造函数的对象实例 this.uname = uname this.age = age } Father.prototype.money = function(){ console.log('2w one month') } // 2.子构造函数 function Son(uname, age, score){ // this 指向子构造函数的对象实例 Father.call(this, uname, age) //把父亲的 this 改成 孩子的 this this.score = score } // Son.prototype = Father.prototype 这样直接赋值有问题 如果修改了子原型对象 父原型对象也会跟着变化 // 如果利用对象的形式修改了原型对象 别忘了利用 constructor 指回原来的构造函数 // 由于 Son.prototype = new Father() 实例对象覆盖了Son.prototype对象 所以需要加一个 constructor Son.prototype.constructor = Son Son.prototype = new Father() // 这个是子构造函数专门的方法 Son.prototype.exam = function(){ console.log('I need to exam') } let son = new Son('张三', 18, 100) console.log(son) console.log(Father.prototype) console.log(Son.prototype.constructor)
四、类的本质
- 类的本质是一个函数。
可以简单的理解为:类就是构造函数的另外一种写法。
class Star{ } console.log(typeof Star) //function
- 类有原型对象 prototype。类所有方法都定义在类的 prototy
pe
属性上。
class Star{ } console.log(Star.prototype)
- 类原型对象 prototype 也有 constructor 指向类本身。
class Star{ } console.log(Star.prototype.constructor)
- 类可以通过原型对象方法添加对象。
class Star{ } Star.prototype.sing = function(){ console.log('无名的人') } let a = new Star('毛不易') console.log(a)
类创建的实例对象有 __proto__ 原型指向类的原型对象。
class Star{ } Star.prototype.sing = function(){ console.log('无名的人') } let a = new Star('毛不易') console.log(a.__proto__ === Star.prototype) //true
- ES6 的类其实就是语法糖。
语法糖:一种便捷方法。简单理解,有两种方法可以实现同样的功能,但是一种写法更加清晰、方便,那这个方法就是语法糖。