JS-原型和原型链

构造函数

1
2
3
4
5
6
7
8
9
10
//构造函数命名时,首字母要大写
function Foo(name, age) {
this.name = name
this.age = age
this.class = 'class-1'
// return this // 默认有这一行
}

var f = new Foo('zhaoxiaocou', 26)
// var f1 = new Foo('coucou', 27) // 创建多个对象

描述 new 一个对象的过程

  1. 创建一个新对象
  2. this 指向这个新对象
  3. 执行代码,即对this 赋值
  4. 返回this

原型规则

1、所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了“null”意外)。

1
2
3
4
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;

2、所有的引用类型(数组、对象、函数),都有一个_proto_属性(隐式原型),属性值是一个普通的对象。

1
2
3
console.log(obj._proto_);
console.log(arr._proto_);
console.log(fn._proto_);

3、所有的函数,都有一个prototype属性(显示原型),属性值也是一个普通的对象。

1
console.log(fn.prototype)

4、所有的引用类型(数组、对象、函数),_proto属性值指向它的构造函数的”prototype”属性值。

1
console.log(obj._proto_ === Object.prototype)

5、当试图得到一个引用类型(数组、对象、函数)的某个属性时,如果这个引用类型本身没有这个属性,那么会去它的__proto_(即它的构造函数的prototype)中寻找。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Foo(name, age) {
this.name = name
}
Foo.prototype.alertName = function () {
alert(this.name)
}
// 创建示例
var f = new Foo('zhaoxiaocou')
f.printName = function () {
console.log(this.name)
}
// 测试
f.printName()
f.alertName()

// toString() 方法返回一个表示该对象的字符串。
// toString() 返回 "[object type]",其中 type 是对象的类型。
console.log(f.toString()) //[object Object], 要去 f._proto_._proto_ 中去找

循环对象自身的属性

1
2
3
4
5
6
7
8
var item 
for (item in f) {
// 高级浏览器已经在for in中屏蔽了来自原型的属性
// 但是这里建议大家还是加上这个判断,保证程序的健壮性
if (f.hasOwnProperty(item)) {
console.log(item)
}
}

如何准确判断一个变量是数组类型

1
2
3
var arr = []
arr instanceof Array // true
typeof arr // object, typeof 是无法判断是否是数据的

原型链继承的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 写一个封装DOM查询的例子
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('div1')
// console.log(div1.html())

div1.html('<p>hello, weizhideziji.</p>')
div1.on('click', function () {
alert('clicked')
})