JavaScript基础4之原型的原型继承、原型链和理解对象的数据属性、访问器属性
温馨提示:这篇文章已超过424天没有更新,请注意相关的内容是否还可用!
JavaScript基础
- 原型
- 原型继承
- 问题
- 解决
- 原型链
- isPrototypeOf()
- Object.getPrototypeOf()
- 理解对象
- 数据属性
- 访问器属性
原型
原型继承
继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript中大多是借助原型对象实现继承的特性。
龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义。
我们来看个代码:
Title //继续抽取 公共的部分放到原型上 const Person= { eyes: 2, head: 1 } //女人 构造函数 继承 想要继承 Person function Woman(){ } //Woman通过原型来继承Person Woman.prototype=Person //指回原来的构造函数 Woman.prototype.constructor=Woman const red= new Woman() console.log(red) console.log(Woman.prototype) //男人 构造函数 继承 想要继承Person function Man(){ } Man.prototype=Person Man.prototype.constructor=Man const pink=new Man() console.log(pink.head) console.log(pink)问题
例如:
给女人加一个生孩子的方法
//给女人添加一个方法 生孩子 Woman.prototype.baby=function (){ console.log("宝贝") }全部代码:
Title //继续抽取 公共的部分放到原型上 const Person= { eyes: 2, head: 1 } //女人 构造函数 继承 想要继承 Person function Woman(){ } //Woman通过原型来继承Person Woman.prototype=Person //指回原来的构造函数 Woman.prototype.constructor=Woman const red= new Woman() console.log(red) console.log(Woman.prototype) //给女人添加一个方法 生孩子 Woman.prototype.baby=function (){ console.log("宝贝") } //男人 构造函数 继承 想要继承Person function Man(){ } Man.prototype=Person Man.prototype.constructor=Man const pink=new Man() console.log(pink.head) console.log(pink)男人和女人都同时使用了同一个对象,根据引用类型的特点,他们指向同一个对象,修改一个就会都影响。
解决
需求:男人和女人不要使用同一个对象,但是不同对象里面包含相同的属性和方法
答案:构造函数
new 每次都会创建一个新的对象
function Star(){ this.age = 18 this.say = function () {} } const ldh = new Star( ) const zxy = new Star() console.log(ldh) console.log(zxy) console.log(ldh === zxy) // false每个实例对象都不一样Title /*//继续抽取 公共的部分放到原型上 const Person= { eyes: 2, head: 1 }*/ //解决 构造函数 new 出来的对象 结构一样 但是对象不一样 function Person(){ this.eyes=2 this.head=1 } //女人 构造函数 继承 想要继承 Person function Woman(){ } //Woman通过原型来继承Person //父构造函数(父类) 子构造函数(子类) //子类的原型 = new 父类 Woman.prototype=new Person() //指回原来的构造函数 Woman.prototype.constructor=Woman //给女人添加一个方法 生孩子 Woman.prototype.baby=function (){ console.log("宝贝") } const red= new Woman() console.log(red) console.log(Woman.prototype) red.baby() //男人 构造函数 继承 想要继承Person function Man(){ } Man.prototype=new Person() Man.prototype.constructor=Man const pink=new Man() console.log(pink.head) console.log(pink)原型链
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链
- 只要是对象就有__proto__,指向原型对象。
- 只要是原型对象就有constructor,指回创造我的构造函数。
当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型(也就是__proto__指向的prototype原型对象)
③如果还没有就查找原型对象的原型(Object的原型对象)
④ 依此类推一直找到Object 为止(null)
⑤ __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
可以使用instanceof 运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上
Title function Person(){ } const ldh=new Person() console.log(ldh.__proto__===Person.prototype); console.log(Person.prototype.__proto__===Object.prototype) console.log(ldh instanceof Person) console.log(ldh instanceof Object) console.log(ldh instanceof Array) console.log([1,3,7] instanceof Array) console.log(Array instanceof Object)正常的原型链都会终止于 Object 的原型对象,Object 原型的原型是 null
console.log(Person.prototype.__proto__ === Object.prototype); // true console.log(Person.prototype.__proto__.constructor === Object); // true console.log(Person.prototype.__proto__.__proto__ === null); // true
function Person(){} console.log(Person.prototype.__proto__); { constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() }isPrototypeOf()
确定两个对象之间的关系
[[prototype]]
isPrototypeOf()会在传入参数的[[Prototype]]指向调用它的对象时返回 true
function Person(){} const person=new Person() console.log(Person.prototype.__proto__); console.log(Person.prototype.isPrototypeOf(person));相当于:
console.log(person.__proto__===Person.prototype) //true
Object.getPrototypeOf()
返回参数的内部特性 [[Prototype]] 的值
console.log(Object.getPrototypeOf(person)===Person.prototype) //true
理解对象
new Object() ==== {}
const person=new Object() person.name="张三" person.age=18 person.say=function(){ console.log(this.name) } person.say()等同于
const person={ name:"张三", age:20, say(){ console.log(this.name) } } person.say()数据属性
- configurable:属性是否可以通过delete 删除并重新定义 ⇒true
- Enumerable:属性是否可以通过for in 循环 =》 true
- writable:属性是否可以被修改 =》 true
- value:属性实际的值undefined
Object.defineProperty
访问器属性
- configurable:属性是否可以通过delete 删除并重新定义 → true
- Enumerable:属性是否可以通过for in 循环 =》 true
- Get:获取函数
- Set: 设置函数
getter
setter
let person ={ year_:2023, age:18 } Object.defineProperty(person,"year",{ get(){ console.log('get') return this.year_ }, set(newvalue){ console.log('set',newvalue) this.year_=newvalue this.age +1 } }) console.log(person.year) person.year =2014 console.log(person.age)











