一日客语:中文:晚上 客语:暗晡am buˊ
function Plant() {}
function Apple() {}
Apple.prototype.shape = 'circle';
Apple.prototype = new Plant();//现在Apple的prototype是放 Plant的实例
const myapple = new Apple();
console.log(myapple.constructor);//[Function: Plant]
使用原型继承会让constructor指向Plant function,使myapple的constructor不是Apple function,从程序码的写法来说明明是建构函式Apple所建立的实例,但显示的建构子会是plant function。
原本constructor可以判断由哪一个函式建立,现在却不是预期的样子
如果使用原型继承又要让constructor是Apple?
语法:Object.defineProperty(obj, prop, descriptor)
对物件设定新属性或修改物件属性回传设定好的物件
Object.defineProperty(定义的物件, 属性,属性描述子)
物件内的每一个属性都有property descriptor
property descriptor | 说明 | |
---|---|---|
configurable | 物件的property 是否可以被修改/删除 | |
enumerable | 物件的property是否被for/in 回圈Object.keys() | |
writable | 物件的property的值是否能被改变 | |
value | 设定属性值 | |
get | 定义取值getter function 可以取得属性值,不能和value/writable一起设定 | |
set | 定义设值setter function 可以设定属性指派的值,不能和value/writable一起设定 |
所以descriptor也是一个物件
这个属性的值可以修改吗
true:可以修改
false:不可以修改
const apple = {};
Object.defineProperty(apple, 'color', {
value: 'red',
writable: false,
});
apple.color = 'gold';
console.log(apple.color);//red
const apple = {};
Object.defineProperty(apple, 'color', {
value: 'red',
writable: true,
});
apple.color = 'gold';
console.log(apple.color);//gold
是否可以被for/in迭代列出
目标:设定apple的shape属性,是不可以被for/in迭代列出
作法:把property descriptor的enumerable设成false
let apple = {};
Object.defineProperty(apple, 'color', { value: 'red', enumerable: true });
Object.defineProperty(apple, 'shape', { value: 'circle', enumerable: false });
Object.defineProperty(apple, 'size', { value: 'small', enumerable: true });
Object.defineProperty(apple, 'price', { value: 10000, enumerable: true });
for (let i in apple) {
console.log(i);
}
//color
//size
//price
取值时,启动get,return 出fruit[0]//apple出去
const map = {
fruit: ['apple', 'orange', 'banana'],
get eat() {
return this.fruit[0];
},
set eat(value) {
this.fruit[0] = value;
},
};
console.log(map.eat);//apple
赋值时,启动set,会把value(water)赋值到fruit[0]
const map = {
fruit: ['apple', 'orange', 'banana'],
get eat() {
return this.fruit[0];
},
set eat(value) {
this.fruit[0] = value;
},
};
map.eat = 'water';
//现在fruit: ['water', 'orange', 'banana']
function Go() {}
function Run() {}
Go.prototype.school = 'sleep';
Run.prototype = new Go();
const student = new Run();
console.log(student.constructor);//[Function: Go]
解决方式:就是在property descriptor 让Apple.prototype的constructor设定为 Apple,且不让他被改写也让他不要出现在for-in回圈
function Plant() {}
function Apple() {}
Apple.prototype.shape = 'circle';
Apple.prototype = new Plant();
const myapple = new Apple();
Object.defineProperty(Apple.prototype, 'constructor', {
value: Apple,
enumerable: false,
writable: false,
});
console.log(myapple.constructor); //Function: Apple]
这样方式既可以继承,constructor也是指向当初建立的函式
学完一整套原型链~赞
资料参考:
忍者开发技巧探秘第二版
mdn
透过前一篇文章的介绍,读者应该了解现今的云端服务相当方便,许多持续交付的功能已经写成 Action,...
运用到的观念: 利用vertical-align: middle;调整图片预设多余的空间 使用po...
设计大纲 上一个区块设计了使用者的「痛点」,因此接下来的区块想要做一个「平台的小广告」,让使用者了解...
梯度下降法经常被使用为优化学习的一种方式,寻找局部最佳解(至於为何是局部,之後会提到),想像有个...
声音这东西实在是太自然了,所以我们很少去思考这东西的本质到底是什麽 简单的来复习一下声音是什麽,你...