构造函数:
是一种特殊的方法,主要用来创建对象时初始化对象,及对象成员变量赋初始值
与普通的函数区别:函数名首字母大写,调用时使用new关键字调用
function Person(name,age){
this.name=name
this.age=age
this.sayHi=function(){
alert('hello')
}
}
let person1=new Person('zhangsan',13);
console.log(person1)
//Person{name:'zhangsan',age:'13',sayHi:f}
创建了不同的类,每次new这个函数都会给创建的对象添加sayHi这个方法,这样就导致构造函数执行一次创建一个新方法,所以为了简化这个执行步骤,就用到了原型
原型
在JavaScript中,每定义一个函数或类时,都会有一个prototype属性,指向原型对象
原型对象相当于一个公共的存放区,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中
原型链
每一个对象数据类型(对象、实例、prototype)都带有一个属性__proto__ 这个属性不规范但是很多程序员都在用,原型对象中也有一个属性constructor,指向函数对象
function Person(){}
let person =new Person()
console.log(person.__proto__===Person.prototype) //true
console.log(Person.prototype.constructor===Person) //true
console.log(Object.getPrototypeOf(person)===Person.prototype)//true
当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。如果没有则去原型的原型中寻找,直到找到Object对象的原型,Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined。
我们可以使用对象的hasOwnProperty()
来检查对象自身中是否含有该属性;使用in
检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
function Person() {}
Person.prototype.a = 123;
Person.prototype.sayHello = function () {
alert("hello");
};
var person = new Person()
console.log(person.a)//123
console.log(person.hasOwnProperty('a'));//false
console.log('a'in person)//true
person实例中没有a这个属性,从 person 对象中找不到 a 属性就会从 person 的原型也就是 person.__proto__
,也就是 Person.prototype中查找,很幸运地得到a的值为123。那假如 person.__proto__
中也没有该属性,又该如何查找?
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层Object为止。Object是JS中所有对象数据类型的基类(最顶层的类)在Object.prototype上没有__proto__
这个属性。
(参-简书-浪行舟)