构造函数
一般情况下我们通过构造函数创建一个对象实例。我们实例对象中的属性和方法都会定义在构造函数内部。
function Person(name = '',age = ''){
this.name = name;
this.age = age;
this.info= function(){
console.log(`名字:${this.name},年龄:${this.age}`)
}
}
const person1 = new Person('person1',20);
如上,Person是一个标准构造函数,内部设定了name和age两个属性加info的一个方法,在实例上也会相应的出现这两个参数和info事件。
但是有一个问题是当我们需要创建很多个实例时,上面的写法会导致我们创建很多次info事件。会造成一定的资源浪费。
prototype
JS继承机制的思想就是所有原型对象上的属性和方法都会被实例对象所共享。也就是说,当我们把公共的方法或属性定义在原型对象上时,示例对象也是可以使用的,而且更加节省资源
js规定没个函数都有prototype属性,它指向一个对象
function f(){}
typeof(f.prototype) //object
function Person(name = '',age = ''){
this.name = name;
this.age = age;
}
Person.prototype.info = function () {
console.log(`名字:${this.name},年龄:${this.age}`)
}
const person1 = new Person('person1',20);
person1.info();
如上我们将Person的info方法通过prototype属性进行挂载,person1示例也是照样使用的。
原型对象属性并不是实例对象的属性,只要修改原型对象上的属性,立马就会体现在实例对象上
原型链
JS规定所有的对象都有自己的原型对象(prototype)。一方面任何一个对象都可以充当其他对象的原型对象。另一方面,原型对象也是对象,它也有自己的原型对象。因此形成了“原型链”。也就是 示例==>原型==>原型的原型。
如果一直一层一层网上,所有的对象都可以追溯到Object.prototype上,也就是所有的对象都是继承了Object.prototype的属性,这就是所有对象都有valueOf和toString方法的原因。
但是Object.prototype它的原型是null,也就是说所有的对象都可以追溯到null上,就无法再继续追溯。null便是原型链的尽头
顺便提下,instanceof判断类型的原理就是类似于原型式的查找判断。所有会有下面的例子
const date = new Date();
console.log(date instanceof Object); //true
console.log(date instanceof Date); //true
console.log(Date instanceof Object); //true
这个东西算不上坑,但是我们在判断数据类型时,不能全依赖于typeof或者instanceof。
完结,撒花