前端JS知识要点总结(2)

时间:2021-12-15 17:59:59

原型和原型链

这部分主要涉及六以下知识点:
- 构造函数
- 构造函数扩展
- 原型规则和示例
- 原型链
- instanceof

原型——[[prototype]],是js中的对象的一个特殊的内置属性

强调:JavaScript中只有对象,没有类!

下面的代码是一个对象创建的例子

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('abc', 21)

对于原型而言,共有5条规则:
1 所有的引用类型(数组,对象,函数)都具有对象特性,即可以*扩展属性

var obj = {}
obj.a = 100

var arr = []
arr.a = 100

function fn(){}
fn.a = 100

2 所有的引用类型(数组,对象,函数)都有一个’__proto__’属性,属性值是一个普通的对象

console.log(obj.__proto__)
console.log(arr.__proto__)
console.log(fn.__proto__)

// output
{}
[]
[Function]

3 每个构造函数有一个prototype属性,属性值也是一个普通的对象

console.log(obj.prototype)
console.log(arr.prototype)
console.log(fn.prototype)

// output
undefined
undefined
fn(){}

4 所有的引用类型(数组,对象,函数)的’__proto__’属性值都指向它的构造函数的prototype的属性值(这句话不完全正确,有特殊情况,但是不必刻意讨论)

console.log(obj.__proto__ === Object.prototype)
console.log(arr.__proto__ === Array.prototype)
console.log(fn.__proto__ === Function.prototype)

// output
true
true
true

5 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的’__proto__’中寻找

function Foo(name, age) {
this.name = name
}
Foo.prototype.alertName = function() {
alert(this.name)
}
var f = new Foo('zhangsan')
f.printName = function() {
console.log(this.name)
}
f.printName()
f.alertName()
console.log(f.__proto__)
console.log(f.prototype)

// output
zhangsan //(console.log)
zhangsan //(alert)
Foo { alertName: [Function] }
undefined

下面的图是关于__proto__的一张图,是我自己画的,仅用于理解__proto__
前端JS知识要点总结(2)

最后总结一下_proto__和prototype的知识点

在原型的知识点方面,要注意最重要的是__proto__,而不是prototype,因为prototype只是在函数中才存在的,而__proto__是在所有的对象中都存在的。

此外判断原型继承时,要通过new操作符的使用来判断。也就是如果

var a = new A

或者

var a = new A() // 我觉得还是这种写法比较标准,虽然上面那种并不会报错,也见到有人用过,但是看起来不习惯,有可能造成误解

那么a的原型就是A,在程序代码方面,a.__proto__就是A.prototype。这个说法很奇怪,但是就是这么规定的,因此如果a中无法找到是属性,例如a.name,就要在A.prototype中去找,注意是A.prototype而不是A!

题目六:如何准确判断一个变量是数组类型

var arr = []
arr instanceof Array // true
typeof arr // object

typeof操作符:用于检测给定变量的数据类型,返回结果是个字符串:未定义,布尔值,字符串,数字,对象,函数。注意:并不包括数组这种类型的结构,别搞混了!

  • “undefined”这个值未定义
  • “boolean”
  • “string”
  • “number”
  • “object”
  • “function”

instanceof:中文意思是“实例”
用于判断a是否为A的实例,即: a instanceof A

所以如果需要判断一个变量是否为数组,则应该使用: a instanceof Array

最后举一个例子,说明一下 “object” 和Object的用法区别:

var a = {
name: "wufan"
}
console.log(typeof a) //"object"
console.log(a instanceof Object) // true
// console.log(a instanceof object) //这句话不符合语法规则,会报错,注意Object和object的区别

题目七:写一个原型链继承的例子

参照上面图中代码即可

题目八: 描述new一个对象的过程

  1. 创建一个新对象
  2. 这个新对象会被执行[[prototype]]连接
  3. this指向这个新对象,即被绑定在函数调用的this
  4. 如果函数没有返回其他对象,那么将会默认返回this指向的新对象

题目九: zepto(或其他框架)源码中如何使用原型链

阅读源码是高效提升技能的方式,但是不能埋头苦钻,多看源码分析的文章,有目的性的去理解源码