Fork me on GitHub

prototype

原型链,继承,克隆,作用域与闭包

原型与原型链及其特点

原型

在每一个对象内部都会初始化一个属性,即prototype

原型链

当我们访问一个对象的属性的时候,如果没有访问到,就会寻找他的prototype属性,而prototype还有其prototype属性,就这样一直找下去,就是原型链。

特点

当我们改变原型属性时,与之对应的对象也会继承这一属性。

hasOwnProperty 查找对象本身属性

创建对象的几种方式

  • 对象字面量

var o1 = {name: ‘o1’};

  • 构造函数

var o1 = new Object({name:’o1’});

  • 立即执行函数

var o1 = (function(){return {name:’o1’}}());

  • Object.create

var p = {name:’o1’};
var o1 = Object.create(p);

new 对象过程

  • 创建新对象
  • this指向这个新对象
  • 执行代码
  • 返回this

继承

js如何实现继承

构造继承,原型继承,实例继承,拷贝继承,对象冒充,组合继承

构造继承

function Parent(){
this.name = ‘parent’;
}
function Child(){
Parent.call(this);
this.type = ‘child’;
}

缺点:部分继承 继承不到父类原型链上的方法

原型继承

function Parent(){
this.name = ‘parent’;
}
function Child(){
this.type = ‘child’;
}

Child.prototype = new Parent()

缺点:原型链上的原型对象是共用的。

对象冒充

function Parent(){
this.name = ‘parent’;
}

function Child(){
this.temp = Parent;
this.temp();
delete this.temp;
this.type = ‘child’;
}

缺点: 不能多重继承

组合继承

function Parent(){
this.name = ‘parent’;
}
function Child(){
Parent.call(this);
this.type = ‘child’;
}

Child.prototype = new Parent()

缺点:父类执行两次,constructor指向父类

改进:
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child

克隆

方法一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function clone(obj){
var o;
if(obj.costructor == Object){
o = new obj.construtor()
}else{
o = new obj.construtor(obj.valueOf())
}
for(key in obj){
if(typeof obj == 'object'){
o[key] = clone(obj[key])
}else{
o[key]= obj[key];
}
}
return o;
}
方法二:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function clone(obj){
var o;
if(typeof obj == 'object'){
if(obj == null){
o = null;
}else{
if(obj instanceof Array){
o = [];
for(var i = 0,len = obj.length;i<len;i++){
o[i] = clone(obj[i]);
}
}else{
o = {};
for(key in obj){
o[key] = clone(obj[key]);
}
}
}
}else{
o = obj;
}
return o;
}

作用域

概念

变量和函数的可访问范围。

特点

没有块级作用域
只有函数和全局作用域

变量提升

变量声明和函数体都会提升到方法体的顶部。

eg:函数声明和函数表达式区别

核心: 函数体会不会被变量提升

1
2
3
4
5
alert(sum({x:10,y:10}));
function sum(obj){
return obj.x+obj.y;
}
=>20
1
2
3
4
5
alert(sum({x:10,y:10}));
var sum = function (obj){
return obj.x+obj.y;
}
=>sum is not a function

闭包

概念

在内部函数访问外部函数中的变量。

作用

封装变量,收敛权限。

使用场景

函数作为返回值
函数作为参数传递

this
有对象指向对象
没对象指向全局变量
有new 指向new出来的对象
apply,bind,call改变this指向
1
2
3
4
5
6
7
8
eg:
var baz = 3; var bazz={ baz: 2, getbaz: function(){return this.baz } }
console.log(bazz.getbaz())
=> 2
var g = bazz.getbaz; console.log(g()) ;
=> 3
这题考察的就是this的指向,函数作为对象本身属性调用的时候this指向对象,作为普通函数调用的时候就指向全局了

this要在执行时才能确认值,定义时无法确认。
-------------本文结束感谢您的阅读-------------