首先,先来了解一下创建对象的三种方法:
1.利用 new Object() 创建对象 var obj1 = new Object()
2.利用对象字面量创建对象 var obj2 = {}
3.利用构造函数创建对象
function Star(uname, age) {
this.uname = uname;
this.age = age;
this.sing = function() {
console.log('唱歌')
}
}
var yyqx= new Star('易烊千玺', 20)
yyqx.sing()
我们为什么需要使用构造函数,就是因我们前面两种创建对象的方式一次只能创建一个对象,因为我们一次创建一个对象,里面很多的属性和方法是大量相同的 我们只能复制,因此我们可以利用函数的方法重复这些相同的代码,我们就把这个函数称为构造函数,又因为这个函数不一样,里面封装的不是普通代码,而是对象 ,构造函数就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面。
但构造函数存在浪费内存的问题
解决方法:prototype 构造函数原型
Star.prototype.sing = function () {
console.log('唱歌')
}
// 一般情况下,我们的公共属性定义到构造函数里面,公共的方法我们放到原型对象身上。
// 原型是一个对象,其作用就是共享方法。
对象原型 __proto__ :实例对象身上系统自己添加一个__proto__ 指向我们构造函数的原型对象 prototype
原型constructor构造函数:对象原型 __proto__ 和构造函数的原型对象 prototype 里面都有一个constructor属性,我们称其为构造函数,因为它指回构造函数本身。constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
原型链
如下图所示,蓝色的线即为原型链:
在构造函数中,里面的this指向的是对象实例。原型对象函数里面的this 指向的也是实例对象
扩展内置对象:
console.log(Array.prototype)
Array.prototype.sum = function() {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i]
}
return sum
}
var arr = [1, 2, 3]
console.log(arr.sum())
console.log(Array.prototype)
var arr1 = new Array(11,22,11)
console.log(arr1.sum())
继承
ES6之前并没有给我们提供extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承
首先了解一下 call() 的作用:可以调用这个函数,并且修改this指向
function fn (x,y) {
console.log('hahahaha')
console.log(this) // 未改时的this指向window
console.log(x+y)
}
var o = {
name: 'yyqx'
};
fn(); // 原始调用方法
fn.call(); // 使用call方法调用函数
fn.call(o,1,2) // 改变函数中的this指向 此时fn这个函数中的this就指向了o这个对象
借用父构造函数继承属性和方法:
// 父构造函数
function Father(uname, age) {
// this指向父构造函数的对象实例
this.uname = uname;
this.age = age
}
// 方法的继承
Father.prototype.money = function () {
console.log(1000)
}
// 子构造函数
function Son(uname, age) {
// this指向子构造函数的对象实例
Father.call(this, uname, age) // 将父构造函数中的this换成子构造函数中的this 即此时父构造函数中的this指向为子构造函数的对象实例son
}
// Son.prototype = Father.prototype // 这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起被修改
Son.prototype = new Father() // 这是正确的写法
// 如果利用对象的形式修改了原型对象,需要利用constructor指回原来的构造函数
Son.prototype.constructor = Son
// 子构造自己特有的方法
Son.prototype.exam = function () {
console.log('中戏双料第一')
}
var son = new Son('易烊千玺', 20)