前置知识
- 只有函数才有prototype(原型)属性。当函数创建后,会自动添加这个prototype。
- 每个对象都有proto属性,proto指向构造函数的原型对象
- 原型对象也是对象,所以也会有proto,于是就这样有了对象和原型对象之间的关系,这样的一条链,就是原型链
使用原型的好处
- 多个实例之间共享属性和方法
- 减少内存消耗(因为共享了属性和方法了,就不需要重新为新的属性和方法开拓新的内存了)
对象的创建
// 字面量
let a = { name: '张三' }
// 构造函数
function A() {
this.name = '张三'
}
let a = new A()
new这个操作符做了什么工作
function Person() {}
let a = new Person()
// new所做的工作
let obj = {}
obj.__proto__ = Person.prototype
Person.call(obj)
return obj
注意点:
// 在实例后,以下这种写法会导致a.__proto__无法追踪(实例前是可以这么写的,不影响)
let a = new Person()
Person.prototype = {
name: '11'
}
// a.name => undefine
// 这种写法,a.__proto__还是能追踪到
Person.prototype = {
name: '11'
}
let a = new Person()
a.name => '11'
为了避免这种问题,还是建议用
Person.prototype.name = '11' // 并没有重新定义新的prototype,所以能追踪到
题目:
// 挑战一
// 1.定义一个构造函数 Animal,它有一个 name 属性,以及一个 eat() 原型方法。
// 2.eat() 的方法体为:console.log(this.name + " is eating something.")。
// 3.new 一个 Animal 的实例 tiger,然后调用 eat() 方法。
// 4.用 __proto__ 模拟 new Animal() 的过程,然后调用 eat() 方法。
var Animal = function(name){
// 待补充的代码
};
var tiger = new Animal("tiger");
// 待补充的代码
var tiger2 = {};
// 待补充的代码
// 挑战二
// 1.定义一个构造函数 Bird,它继承自 Animal,它有一个 name 属性,以及一个 fly() 原型方法。
// 2.fly() 的方法体为:console.log(this.name + " want to fly higher.");。
// 3.new 一个 Bird 的实例 pigeon,然后调用 eat() 和 fly() 方法。
// 4.用 __proto__ 模拟 new Bird() 的过程,然后用代码解释 pigeon2 为何能调用 eat() 方法。
var Bird = function(name){
// 待补充的代码
}
var pigeon = new Bird("pigeon");
// 待补充的代码
var pigeon2 = {};
// 待补充的代码
// 挑战三
// 1.定义一个构造函数 Swallow,它继承自 Bird,它有一个 name 属性,以及一个 nesting() 原型方法。
// 2.nesting() 的方法体为:console.log(this.name + " is nesting now.");。
// 3.new 一个 Swallow 的实例 yanzi,然后调用 eat()、fly() 和 nesting() 方法。
// 4.用 __proto__ 模拟 new Swallow() 的过程,然后用代码解释 yanzi2 为何能调用 eat() 方法。
var Swallow = function(name){
// 待补充的代码
}
var yanzi = new Swallow("yanzi");
// 待补充的代码
var yanzi2 = {};
// 待补充的代码
// 题目要求:
// 创建一个shape对象,该对象有一个type属性和getType()方法;
// 定义一个原型为shape的Triangle()构造函数,用Triangle()创建的对象应有三个对象属性—-a、b、c,分别用于表示三角形的三条边
// 在对象原型中添加一个名为getPerimeter()的新方法,用下面的代码来进行测试:
var t = new Triangle(1,2,3);
t.constructor===Triangle;——true
shape.isPrototypeOf(t);——true
t.getPerimeter();——6
t.getType();——"triangle"
自己写的答案
let shape = { type: 'triangle', getType: function () { return this.type } }
function Triangle (a, b, c) {
this.a = a
this.b = b
this.c = c
}
shape.constructor = Triangle
shape.getPerimeter = function () { return 6 }
Triangle.prototype = shape
推荐文章:
https://juejin.im/post/585953a5128fe10069b5f06b (看完懂了很多)
https://www.cnblogs.com/wangfupeng1988/tag/%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%93%BE/ (王福朋)
网友评论