用栗子说this
Bug
年年有,本年迥殊多
关于JavaScript
这么天真的言语来讲,少了this
怎样活!
function
函数 this
关于没有实例化的function,我们称之为函数,即没有用new症结字挪用的函数,对它们来讲,this一概指代全局。
上栗子
var position = "outer";
function test(){
position = "inner";
}
console.log(this.position); // outer
test();
console.log(this.position); // inner
缘由:内部未用var声明发作“变量提拔”,污染全局变量。
组织函数 this
关于被实例化的function,我们称之为组织函数,及运用new症结字挪用的function,关于它们来讲,this会被转变,指向实例。
上栗子
var name = 'person'; // 全局this赋上属性name
function Person(name){
this.name = name;
this.say = function () {
console.log('My name is '+this.name);
}
this.show = function () {
console.log(this);
}
}
var william = new Person('william'); //经由过程new症结字建立实例,转变函数内部this指向
console.log(this.name); //person
william.say(); //My name is william
william.show(); //Person {name: "william", say: ...
注解:经由过程这个栗子,我们能够看出,经由过程建立组织函数的实例,使得this的指向转变,指向了实例自身。
原型对象 this
每个函数对象在建立的时刻,都邑自动增加一个prototype属性,这个prototype实际上是一个指针,指向这个函数的原型对象。
你能够经由过程prototype指针给这个函数对象的原型对象增加属性,在实例化函数对象后,能够经由过程this来接见原型对象上的属性。
上栗子
function Person(){
console.log(this.name);
}
Person.prototype.name = "william"; //给原型对象上赋name属性
var person = new Person(); // 经由过程this.name接见原型对象上的属性,打印 "william"
这还不够,我们为函数对象直接增加同名,而不在原型对象上增加
function Person(){
this.name = "Jack";
console.log(this.name);
}
Person.prototype.name = "william";
var person = new Person(); // 打印 "Jack"
这里有一个值得注意的处所:
当你
组织函数
中存在和原型对象
中同名
的属性
或要领
时,原型对象中的属性或要领会被隐蔽
,你只会接见到组织函数中的属性或要领`
Object.create
this
经由过程Object.create建立函数对象实例,而不运用new症结字,也就是说它不会去挪用组织函数
上栗子
function Person(name){
this.name = name;
this.showName = function () {
console.log(this.name + ' in constructor');
}
} //在组织函数中的属性和要领,均同名
Person.prototype.name = "jack";
Person.prototype.showName = function () {
console.log(this.name + ' in prototype');
};
//在原型对象中的属性和要领,均同名
var william = new Person("william");
var jack = Object.create(Person.prototype);
william.showName(); // william in constructor
jack.showName(); // jack in prototype
注解:
- 运用new症结字制造的实例挪用了组织函数的属性和要领
- 运用Object.create制造的实例挪用了原型对象的属性和要领
原型链 this
原型链用于完成继承,当没有找到须要属性或要领时,会顺着原型链向上继承寻觅。
上栗子
function Father(){
this.name = 'father';
} //能够看作"父类"
Father.prototype.showName = function () {
console.log(this.name);
};
function Son(){
this.name = 'son';
} //能够看作"子类"
Son.prototype = new Father(); //这步是症结!
var mike = new Son();
mike.showName(); // son
注解:
- 起首要强调的是JavaScript中没有"父类","子类","继承"如许的东西,我们只是经由过程原型链来完成如许的设想形式。
- 经由过程这一步
Son.prototype = new Father();
我们将"子类"的prototype指针指向了"父类"函数对象
设想形式:继承
为何如许就可以完成继承呢?
起首要想邃晓为何实例能接见组织函数的原型对象
在JavaScript中,有一个内部的属性,在火狐,谷歌浏览器中,将这个内部属性暴露了出来,就是它 __proto__
上栗子(浏览器中)
mike.__proto__ // Father {name: "father", showName: function}
Son.prototype //Father {name: "father", showName: function}
mike.__proto__ === Son.prototype // true
经由过程这个内部属性,我们能够接见到实例的组织函数的原型对象
再来一枚(浏览器中)
mike.__proto__.__proto__ //Father {showName: function}
Father.prototype //Father {showName: function}
mike.__proto__.__proto__ === Father.prototype // true
我们如今经由过程__proto__接见到了"父类"的原型对象!
继承得以完成!
补充一句:
我们能够接见到Son的name属性的值,却接见不到Father的name属性的值,是因为
- mike是Son的实例(实例能做什么...?)
- Father中的name没有对外开放,能够看作是私有属性
总结
重要探讨了
– function
作为函数、组织函数、原型对象时,this
的指代状况
– 扩大了另一种实例化体式格局Object.create
– 细说了原型链道理和完成,模拟了继承的设想形式