构造函数
其实就是一个普通函数,但是内部使用了this变量。
对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。
构造函数首字母最好是大写。
//创建构造函数
function Foo(name,age){
this.age = age;
this.name = name;
}
//创建实例
var f = new Foo("Tim",20)
构造函数扩展
引用类型都是构造函数。
var a = {} 其实就是 var a = new Object( )
var b = [] 其实就是 var a = new Array( )
function Foo(){} 其实就是 var a = new Function( )
实际使用,还是选用前面的方式好一些。
constructor属性
每个实例对象都有一个constructor属性,指向它的原型对象。
实例对象 .constructor == 构造函数
instanceof 验证原型对象与实例对象之间的关系
如,判断一个变量是否为数组对象的实例: 变量名 instanceof Array
原型规则和实例
原型规则
所有的引用类型(数组、对象、函数),都可以自由扩展。(null除外)
所有的引用类型(数组、对象、函数),都有一个
_proto_属性
(隐式原型),属性值是一个普通对象。所有的函数(不包括数组、对象),都有一个
prototype属性
(显式原型),属性值也是一个普通对象。所有的引用类型(数组、对象、函数),
_proto_属性
指向prototype属性
的属性值。也就是说,隐式原型 === 显式原型的属性值。当试图得到一个对象的某一个属性,如果它本身没有这个属性,它会去找
_proto_
(即它的构造函数的prototype
)。
原型链
//构造函数
function Foo(age,name){
this.name = name;
}
Foo.prototype.alertName = function () {
alert(this.name);
}
//创建实例
var f = new Foo("Tim");
//调用
f.toString(); // 要去f._proto_._proto_
在这个例子中,f自身没有toString()方法,它需要去_proto_
也就是Foo.prototype
找。
可是Foo.prototype
也没有,所以需要再往上一级f._proto_._proto_
,也就是Object.prototype
找。
原型验证方法
1. isPrototypeOf( ) 是否是原型
原型(prototype对象).isPrototypeOf(实例对象)
2. hasOwnProperty( ) 属性是否继承来的
实例对象.hasOwnProperty("属性名")
3. in运算符 是否含有某个属性(包含继承来的)
"属性名" in 实例对象
例题讲解
如何判断一个变量是数组类型
注意,typeof是无法判断的!
instanceof才能判断引用类型的变量。
var arr = [];
arr instanceof Array; //true
原型继承例子
function Elem(id){
this.elem = document.getElementById("id");
}
Elem.prototype.html = function (value){
var elem = this.elem;
//如果传参数,就将它参数设为innerHTML
if(value){
elem.innerHTML = value;
return this; //这样可以做链式操作
//否则,将返回innerHTML的内容
}else{
return elem.innerHTML;
}
}
Elem.prototype.on = function (type,fn){
var elem = this.elem;
elem.addEventListener(type,fn);
return this;
}
//创建Elem实例对象
var div1 = new Elem("divOne");
div1.html('<p>Hello Wordld</p>').on('click',function(){alert("成功链式操作")})
new一个对象的过程
创建一个构造函数实例对象
原来构造函数中的this指向这个实例对象