Comments (6)
简单回顾下构造函数,原型和实例的关系:
每个构造函数(constructor)都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针,而实例(instance)都包含一个指向原型对象的内部指针.
组合继承:
基本思路: 使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承.
const Father = function(name) {
this.name = name
this.height = 180
}
// 父类的原型方法
Father.prototype.sayName = function() {
console.log(this.name)
}
// 子类
const Child = function(name) {
Father.call(this, name)
}
Child.prototype = new Father()
// 子类实例1
const child1 = new Child('Gogo')
child1.sayName() // => Gogo
// 链式查找
child1
// 修改继承的属性
child1.height = 60
// 子类实例2
const child2 = new Child('Coco')
child2.sayName() // => Coco
console.log(child2.height) // => 180
实例child1和实例child2都继承了Father的属性和方法且互不干扰,
但是这种实现方式使Father这个父类的构造函数被调用了两次。
Note:
使用构造函数可以避免原型上运用类型属性的共享;
call方法可以实现向父类传递参数;
原型继承
采用ES6的Object.create()方法
const person = {
skinColor: ['black', 'white', 'yellow']
}
let gogo = Object.create(person)
gogo.skinColor.push('red')
let coco = Object.create(person)
coco.skinColor.push('blue')
console.log(person.skinColor) // => ["black", "white", "yellow", "red", "blue"]
可看出skinColor在gogo的原型属性上
Object.create的第二个参数与Object.defineProperties()方法的第二个参数格式相同:
每个属性都是通过自己的描述符定义的,以这种方式指定的任何属性都会覆盖原型对象上的同名属性。例如:
let aa = Object.create(person, { skinColor: { value: 'blackAndWhite' } })
提醒: 原型式继承中, 包含引用类型值的属性始终都会共享相应的值, 就像使用原型模式一样
new 的实现过程:
比如要实例化类F
const obj = {}
obj.__proto__ = F.prototype
F.call(obj)
属性查找
hasOwnProperty
判断属性是否为对象自身的属性,不会去原型上查找
instanceof 和 isPrototypeOf
isPrototypeOf 用来判断该方法所属的对象是否为参数的原型对象,比如:
console.log(Father.prototype.isPrototypeOf(child1))
instanceof 用来判断对象是否为构造器的一个实例
from drx.
this 根本不受原型的影响
无论在哪里找到方法:在对象或者原型中。调用方法时,this 始终是点之前的对象。
因此,实际上 setter 使用 admin 作为 this,而不是 user。
这是一件非常重要的事情,因为我们可能有一个有很多方法而且继承它的大对象。然后我们可以在继承的对象上运行它的方法,它们将修改这些对象的状态,而不是大对象的。
例如,这里的 animal 代表“方法存储”,而且 rabbit 在使用它。
调用 rabbit.sleep(),在 rabbit 对象上设置 this.isSleeping:
// animal has methods
let animal = {
walk() {
if (!this.isSleeping) {
alert(`I walk`);
}
},
sleep() {
this.isSleeping = true;
}
};
let rabbit = {
name: "White Rabbit",
__proto__: animal
};
// modifies rabbit.isSleeping
rabbit.sleep();
alert(rabbit.isSleeping); // true
alert(animal.isSleeping); // undefined (no such property in the prototype)
from drx.
每个函数都有 "prototype" 属性,即使我们不设置它。
默认的 "prototype" 是一个只有属性 constructor 的对象,它指向函数本身。
像这样:
function Rabbit() {}
/* default prototype
Rabbit.prototype = { constructor: Rabbit };
*/
from drx.
JavaScript 本身并不能确保正确的 "constructor" 函数值
是的,它存在于函数的默认 "prototype" 中,但仅此而已。之后会发生什么 —— 完全取决于我们自己。
特别是,如果我们将整个默认原型替换掉,那么其中就不会有构造函数。
例如:
function Rabbit() {}
Rabbit.prototype = {
jumps: true
};
let rabbit = new Rabbit();
alert(rabbit.constructor === Rabbit); // false
因此,为了确保正确的 "constructor",我们可以选择添加/删除属性到默认 "prototype" 而不是将其整个覆盖:
function Rabbit() {}
// Not overwrite Rabbit.prototype totally
// just add to it
Rabbit.prototype.jumps = true
// the default Rabbit.prototype.constructor is preserved
或者,也可以手动重新创建 constructor 属性:
Rabbit.prototype = {
jumps: true,
constructor: Rabbit
};
// 这样的 constructor 也是正确的,因为我们手动添加了它
from drx.
function Rabbit() {}
Rabbit.prototype = {
eats: true
};
let rabbit = new Rabbit();
delete rabbit.eats;
alert( rabbit.eats ); // true
所有 delete 操作都直接应用于对象。这里 delete rabbit.eats 试图从 rabbit 中删除 eats 属性,但 rabbit 对象并没有 eats 属性。所以这个操作不会有任何 副作用。
from drx.
let user2 = new Object('Pete')
内置的 Object 构造函数忽略参数,它总是创建一个空对象 —— that's what we got from user2。
from drx.
Related Issues (15)
- 深入了解js拷贝(赋值与引用)
- 深入了解VUE
- React-Native - 知识收集整理 HOT 1
- JS作用域和变量提升 HOT 1
- 服务端渲染
- 开发中比较实用的JS技巧类 HOT 6
- ES6 新特性相关
- 算法与数据结构
- JS基础算法相关(数组,字符串处理等)
- 微信小程序使用总结 HOT 1
- 混合web app开发相关手记 HOT 12
- 面试相关 HOT 2
- React开发手记 HOT 1
- Typescript相关 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from drx.