原型
/*
对象中存储属性的区域有两个:
1.对象自身
直接通过对象所添加的属性
在类中通过x=y形式所添加的属性(包括箭头函数、set = function(){}形式)
2.原型对象(prototype)
会帮助对象存储一些属性
在对象中会有一个属性用来存储原型对象,叫__proto__
当访问对象的属性时,优先访问对象本身,当没有时,则去访问对象的原型
会添加到原型对象的情况:1.在类中通过使用xxx(){}声明的方法。2.主动向原型里添加
*/
class person{
name
gender
age
sayhello(){
}
}
/*
原型对象中的数据:对象中的数据(属性和方法),consructor(对象的构造函数)
原型对象也有原型,这样就构成了一条原型链,根据对象的复杂程度不同,原型链的长度也不同
原型链 例如:实例对象-->原型-->原型(object对象的原型)-->null
作用域链是找变量的值,找不到会报错;原型链是找属性的值,找不到会报undefined
所有的同类对象他们的原型对象都是同一个
原型的作用:相当于的一个公共空间,可以被所有的实例访问。
可以将一个该类实例中所有的公共属性统一存放到原型中,这样只需创建一个属性,就可以被所有实例访问。
对象中有些值是私有的例如(name,age,gender)
js中继承就是通过原型实现的:当继承时,子类的原型就是父类的实例
*/
class animal{
}
class cat extends animal{
}
class tomCat extends cat{
}
//tomCat-->cat-->animal实例-->object-->Object原型-->null
函数的–proto–是f(),f()的–proto–是Object原型
修改原型
尽量不要手动修改原型
不要通过类的实例去修改,会影响所有同类对象
可以通过类的prototype属性来访问实例的原型
/*
可以使用instanceof检查一个对象是否由一个类创建的,
instanceof检查的是对象的原型链上是否有该类实例,只要有就返回true
dog -> animail实例 ->object实例 ->Object原型
*/
class animali{ }
class Dog extends animail{}
cosnt dog = new Dog() //相当于const dog = {} 就是一个对象object
/*
检查一个对象自身是否具有一个属性方法
*/
//1.in 使用in时,会检查对象自身和原型
console.log("name" in p )
//2.对象.hasOwnProperty(属性名) 不推荐
console.log(p.hasOwnProperty("sayhello"))
//3.Object.hasOwn(对象,属性名)
console.log(Object.hasOwn(p,"name"))
js声明类的旧方法:使用function xx(){} ,声明了一个xx的类
使用new关键字发生了什么
/*
当使用一个new关键字去调用一个函数时,这个函数将会作为构造函数使用
1.创建一个普通的js对象(object对象{}),称为新对象
2.将构造函数的prototype属性设置为新对象的原型
3.使用实参来执行构造函数,并且将新对象设置为函数的this
4.如果构造函数返回的是一个非原始值,则该值会作为new运算的返回值返回,如果构造函数的返回的是一个原始值或者没有指定返回值
则新的对象会作为返回值返回。
*/
function myNew(fn,...args){
var newInstance = {}
newInstance.__proto__ = myNew.prototype
let res = fn.apply(newInstance,...args)
return typeof res === "object" ? res||newInstance : newInstance
}