题目
- 如何准确判断一个变量是数组类型
- 写一个原型链继承的例子
- 描述new一个对象的过程
知识点
- 构造函数
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',25); //创建多个对象
构造函数命名准则:首字母大写
- 构造函数-拓展
- var a = {}其实是var a = new Object()的语法糖
- var a = []其实是var a = new Array()的语法糖
- function Foo(){…}其实是var Foo = new Function(…)的语法糖
- 正常编写代码时依然推荐前者
- 使用instanceof判断一个函数是否是一个变量的构造函数
- 原型规则和示例
5条原型规则:
- 所有的引用类型(数组、对象、函数),都具有对象的特性,即可自由扩展的属性(除了“null”以外)
- 所有的引用类型(数组、对象、函数),都有一个
_proto_
(隐式原型)属性,属性值是一个普通的对象- 所有的函数,都有一个
prototype
(显式原型)属性,属性值也是一个普通的对象- 所有的引用类型(数组、对象、函数),
_proto_
属性值指向它的构造函数的prototype
属性值
示例:
var obj = {};obj.a = 100;
var arr = [];arr.a = 100;
function fn(){};fn.a = 100;
console.log(obj._proto_);
console.log(arr._proto_);
console.log(fn._proto_);
console.log(fn.prototype);
console.log(obj._proto_) === Object.prototype;
- 当试图得到一个引用类型(数组、对象、函数)的某个属性时,如果这个对象本身没有这个属性,那么会去它的
_proto_
(即它的构造函数的prototype
)中寻找
示例:
function Foo(name){
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();
- f本身没有alertName的属性,所以会去f的隐式原型
__proto__
中去寻找,f的隐式原型__proto__
即-为其构造函数Foo的显式原型prototype
,Foo的显式原型已被扩展了alertName
的属性,所以可顺利执行- this永远指向对象本身,在执行f.alertName()的时候会执行到第5行
alert(this.name)
,但是这里的this还是f本身
- 原型链
// 构造函数
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();
f.toString(); // 要去f._proto_._proto_中查找
toString
属性的查找过程:
f.toString()
->f._proto_
->Foo.prototype
->无toString属性
->Foo.prototype是一个对象
->Foo.prototype._proto_
->Object.prototype
->f._proto_._proto_
原型链示意图,方框里是对象,圆角框里是属性
Object.prototype == null
- instanceof
f instancefo Foo的
判断逻辑:
- f 的_proto_一层一层往上,能否对应到Foo.prototype
- 再试着判断f instanceof Object
题目解答
- 如何准确判断一个变量是数组类型
var arr = [];
arr instanceof Array; //true
typeof arr; //object
//typeof无法准确判断数组类型
- 写一个原型链继承的例子
//原型链继承示例————封装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 world</p>');
div1.on('click',function(){
alert('click');
})
- 描述new一个对象的过程
- 创建一个新对象
- this指向这个新对象
- 对this进行赋值
- 返回this