作者:娜是相当滴好4 | 来源:互联网 | 2023-09-18 16:32
申明:此择要笔记系列是我近来看《JavaScript高等程序设计(第3版)》顺手所记。内里分条列举了一些我以为主要的、须要记下的、对我有协助的点,是依据我看的递次来的。择要笔记自身
申明:
此择要笔记系列是我近来看《Javascript高等程序设计(第3版)》顺手所记。
内里分条列举了一些我以为主要的、须要记下的、对我有协助的点,是依据我看的递次来的。
择要笔记自身没有系统性,没有全面性可言,写在这里供有肯定基本的前端开发者参考交换。
内里的知识点、例子大部份来源于本书,或许延长出来的,都经由我的测试是对的,然则没办法保证100%准确,假如有人看到毛病的处所,愿望指出来,感谢。
关于继续
1. 原型链概述
function Grandpa () {
this.name = 'Grandpa'
}
Grandpa.prototype.sayName = function () {
console.log(this.name)
}
function Parent () {
this.name = 'Parent'
}
Parent.prototype = new Grandpa()
Parent.prototype.sayHello = function () {
console.log('hello')
}
var ming = new Parent()
var li = new Parent()
ming.sayName() // 'Parent'
ming.sayHello() // 'hello'
ming.sayHello === li.sayHello // true
ming.sayName === li.sayName // true
ming instanceof Parent // true
ming instanceof Grandpa // true
ming.cOnstructor=== Parent // false 因为在上面从新了 Parent 的原型,而且没有从新指定 constructor
ming.cOnstructor=== Grandpa // true 因为上面没有重写 Grandpa 的原型
ming.__proto__ === Parent.prototype // true
ming.__proto__ === Grandpa.prototype // false
Parent.prototype.__proto__ === Grandpa.prototype // true
2. 肯定原型和实例的关联
两种要领: instanceof 操纵符和 isPrototypeOf(),
如上例:
Parent.prototype.isPrototypeOf(ming) // true
Grandpa.prototype.isPrototypeOf(ming) // true
Object.prototype.isPrototypeOf(ming) // true
3. 给原型增加要领的代码肯定放在替代原型的语句以后,不然无效
4. 原型链的题目
题目1. 援用范例的继续在多个实例之间会同享,无论是原型中增加的属性照样组织函数中增加的属性。如:
function Grandpa () {
this.friends = ['ming', 'li']
}
function Parent () {
}
Parent.prototype = new Grandpa()
var ming = new Parent()
var li = new Parent()
ming.friends.push('wang')
console.log(ming.friends) // ['ming', 'li', 'wang']
console.log(li.friends) // ['ming', 'li', 'wang']
ming.friends === li.friends // true
题目2. 在建立子范例的实例中,不能向超范例的组织函数中通报参数
6. 借用组织函数(或叫捏造对象或典范继续)
可以处理援用范例的继续在多个实例之间同享的题目
如:
function Grandpa () {
this.friends = ['ming', 'li']
}
function Aunt () {
Grandpa.call(this)
}
var ming = new Aunt()
var li = new Aunt()
ming.friends // ['ming', 'li']
ming.friends.push('wang')
li.friends // ['ming', 'li']
ming.friends // ['ming', 'li', 'wang']
7. 借用组织函数可以处理不能向超范例的组织函数中通报参数的题目。
如:
function Grandpa (name) {
this.name = name
}
function Parent (name, age) {
Grandpa.call(this, name)
this.age = age
}
var ming = new Parent('ming', 15)
ming.age // 15
ming.name // 'ming'
注重:这类状况,为了防止超范例的组织函数(Grandpa)重写子范例(Parnt)的属性,应在挪用超范例组织函数后,再增加应该在子范例中定义的属性
8. 借用组织函数的题目。
题目1. 函数没有复用,占用内存多。
题目2. 超范例原型中定义的要领,对子范例而言是不可见的,效果只能运用组织函数形式。
9. 组合继续
有时刻也叫伪典范继续。思绪是,运用原型链对原型属性和要领举行继续,借用组织函数完成对实例属性的继续。
如:
function Grandpa (name) {
this.name = name
this.friends = ['li']
}
Grandpa.prototype.sayName = function () {
console.log(this.name)
}
function Parent (name, age) {
Grandpa.call(this, name)
this.age = age
}
Parent.prototype = new Grandpa()
Parent.prototype.sayAge = function () {
console.log(this.age)
}
var ming = new Parent('ming', 12)
var wang = new Parent('wang', 15)
ming.name // 'ming'
ming.friends // ['li']
ming.friends.push('zhang')
wang.friends // ['li']
ming.sayName() // 'ming'
ming.sayAge() // 12
ming.sayName === wang.sayName // true
ming.sayAge === wang.sayAge // true
ming instanceof Parent // true
ming instanceof Grandpa // true
10. 原型式继续
function object (o) {
function F () {}
F.prototype = o
return new F()
}
实际上,object() 对传入个中的对象执行了一次浅拷贝。如:
var person = {
name: 'wang',
friends: ['li']
}
var person1 = object(person)
person1.name // 'wang'
person1.friends // ['li']
person1.name = 'zhang'
person.name // 'wang'
var person2 = object(person)
person1.friends.push('yang')
person2.friends // ['li', 'yang']
person2.friends === person.friends // true
person1.friends === person.friends // true
这类原型式继续,必需有一个对象作为另一个对象的基本。把基本对象传入 object() 函数,把获得的对象依据详细需求做修正即可。
然则别忘了一切获得的对象援用范例是同享的。
es5 新增了 Object.create() 要领范例了原型式继续。
这个要领接收两个参数,一个用作新对象的原型对象,一个(可选的)为新对象定义分外属性的对象。
在传入一个参数的状况下, Object.create() 和 object() 的行动雷同。
Object.create()的第二个参数与 Object.defineProperties() 的第二个参数花样雷同:每一个属性都是经由过程本身的描述符来定义的。
这类体式格局指定的任何属性都邑掩盖原型对象上的同名属性。
如:
var person = {
name: 'wang',
friends: ['li']
}
var person1 = Object.create(person, {
name: {
value: 'zhang'
},
friends: {
value: ['a', 'b']
}
})
person1.name // 'zhang'
person1.friends // ['a', 'b']
person.friends // ['li']
// 支撑 Object.create() 的浏览器有 IE 9+,Firefox 4+, Safari 5+, Opera 912+, Chrome.
11. 寄生式继续
寄生式继续是与原型式继续严密相干的一种思绪,和工场形式相似。如:
function createAnother (original) {
var clOne= object(original)
clone.sayHi = function () {
console.log('hi')
}
return clone
}
var person = {
name: 'wang',
friends: ['li']
}
var person1 = createAnother(person)
person1.friends // ['li']
person1.sayHi() // 'hi'
新的对象person1不仅具有person的一切属性和要领,另有本身的 sayHi() 要领。
树模的 object() 函数不是必需的,任何可以返回新对象的函数都实用于此形式。
注重:运用寄生式继续来为对象增加函数,会因为不能做到函数复用而降低效率,这一点与组织函数形式相似。
12. 组合继续的题目。
无论什么状况下都邑挪用两次超范例的组织函数。一次是在建立子范例原型的时刻,一次是在子范例组织函数内部。
如:
function Grandpa (name) {
this.name = name
this.friends = ['ming']
}
Grandpa.prototype.sayName = function () {
console.log(this.name)
}
function Parent (name, age) {
Grandpa.call(this, name)
this.age = age
}
Parent.prototype = new Grandpa() // 第一次挪用超范例的组织函数 Grandpa(),
// 此时原型上有一个friends属性(值是['ming'])和name属性(值undefined,因为没有传参)
Parent.prototype.sayHi = function () {
console.log('hi')
}
var wang = new Parent('wang', 15) // 第二次挪用超范例的组织函数 Grandpa(),在 Parent() 函数内部挪用,
// 这一步的操纵, Parent 的实例 wang 的属性会掩盖 Parent 的原型上的同名属性 name
12. 寄生组合式继续
基本形式以下:
function inheritPrototype (subType, superType) {
var prototype = object(superType.prototype)
prototype.cOnstructor= subType
subType.prototype = prototype
}
function Grandpa (name) {
this.name = name
this.friends = ['ming']
}
Grandpa.prototype.sayName = function () {
console.log(this.name)
}
function Parent (name, age) {
Grandpa.call(this, name)
this.age = age
}
inheritPrototype(Parent, Grandpa) // 这里没有挪用超范例的组织函数 Grandpa() ,然则这里挪用了一个函数内部的组织函数
Parent.prototype.sayHi = function () {
console.log('hi')
}
var li = new Parent('li', 20) // 挪用超范例的组织函数 Grandpa(),在 Parent() 函数内部挪用
这类形式的优点是只挪用一次 Grandpa() 组织函数,因而防止了在 Parent.prototype 上建立不必要的、过剩的属性。
作者讲,开发人员普遍以为寄生组合式继续是援用范例最理想的继续范式。
继续部份悉数完毕