JS——原型和原型链
1 知识点
1.1.1构造函数 & 构造函数-扩展
1)
function Foo(name, age) {
this.name = name
this.age = age
this.class = 'class-1'
// return this //默认有这一行
}
var f = new Foo('zhangsan', 20)
2)
var a = {}
其实是var a = new Object( )
的语法糖var a = []
其实是var a = new Array( )
的语法糖function Foo(){...}
其实是var Foo = new Function(...)
- 使用 instanceof 判断一个函数是否是一个变量的构造函数 //变量 instanceof Array
1.1.2 原型规则和实例 & 原型、构造函数、实例、原型链的关系
1)
5条原型规则:(原型规则是学习原型链的基础)
①所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了“null”以外);
②所有的引用类型,都有一个_proto_ 属性(隐式原型),属性值是一个普通对象;
③所有的函数,都有一个prototype(显示原型)属性,属性值也是一个普通的对象;
④所有的引用类型(数组、对象、函数),proto__属性值指向它的构造函数的“prototype”属性值;
⑤当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto(即它的构造函数的prototype)中寻找;
引用类型(有“对象属性”、proto)
函数(有“对象属性”、prototype)
引用类型的__proto__ 指向 构造函数的prototype
2)
1.1.3 原型链
当试图得到一个对象f的某个属性时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的prototype)obj._proto_中去寻找;
当obj._proto也没有时,便会在obj._proto.proto(即obj的构造函数的prototype的构造函数的prototype)中寻找;
1.1.4 instanceof 原理
用于判断 引用类型 属于哪个 构造函数 的方法 /
测试对象的__proto__与构造函数的prototype是否引用同一原型 /
测试构造函数的prototype是否在对象的原型链中的任何位置。/
使用 instanceof 验证对象的构造函数
1.1.5 new 原理 & 过程
1)
new 原理:
①创建一个新对象,并继承构造函数 Foo 的原型对象 Foo.prototype;
②构造函数 Foo被执行,执行时传入相应的参数,并将 this 指定为新的实例;
③判断实例是否为对象,是则返回对象,否则返回构造函数;
2)
new 过程:
① 创建一个新对象
② this 指向这个新对象
③ 执行代码,即对this赋值
④ 返回this
function Foo(name, age) {
this.name = name
this.age = age
this.class = 'class-1'
// return this // 默认有这一行
}
var f = new Foo('zhangsan', 20)
// var f1 = new Foo('lisi', 22) // 创建多个对象
2 问答
题目:
*如何准确判断一个变量是数组类型;
*写一个原型链继承的例子;
*描述 new 一个对象的过程 & 原理;(答案看上面知识点)
*创建对象的方法有哪些;(答案看上面知识点)
*原型链是什么;(答案看上面知识点)
*instanceof 原理;(答案看上面知识点)
*继承的方式有哪些?有什么优缺点?
2.1 如何准确判断一个变量是数组类型
arr instanceof Array
2.2 写一个原型链继承的例子
例子一:
function Elem (id) {
this.elem = document.getElementById (id)
}
Elem.prototype.html = function (val) {
var elem = this.elem
if (val) {
elem.innerHTML = val;
return this
} else {
return elem.innerHTML
}
}
Elem.prototype.on = function (type, fn) {
var elem = this.elem
elem.addEventListener(type, fn)
}
var div1 = new Elem('detail-page')
// console.log(div1.html())
div1.html('<p>hello imooc</p>')
div1.on('click', function( ) {
alert('clicked')
})
例子二:
将子辈的原型设置为父辈的实例——
从超类(或者叫父类) Animal继承其行为的
第一个步骤:创建一个Animal的实例 Object.create(Animal.prototype)
第二个步骤:给子类型(或者子类)设置原型 Dog.prototype = …
重置一个继承的构造函数属性—— Dog.prototype.constructor = Dog;
function Animal() {
}
Animal.prototype = {
constructor: Animal,
eat: function() {
console.log("nom nom nom");
}
};
function Dog() {
}
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog;
let beagle = new Dog();
beagle.eat(); // 应该输出 "nom nom nom"
beagle.constuctor; //返回 function Dog( ) { }