this
解析器在调用函数时,每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this
。
this
指向一个对象,这个对象我们称为函数执行的上下文对象,根据函数的调用方式的不同,this
会指向不同的对象。
- 以函数形式调用时,
this
永远都是window
- 以方法的形式调用时,this`就是调用方法的那个对象。
function han(){
console.log(this);
}
han();
var obj = {
name:"hanmeng",
sayName:han
};
obj.sayName();
其实以函数形式调用就相当于window.han();
this.name
可以调用obj
的name
属性。
工厂对象
通过工厂方法创建对象,可以大批量创建对象。
function createobj(name, age, gender){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
};
return obj;
};
var obj1 = createobj("han",27,"male");
console.log(obj1);
obj1.sayName();
使用工厂方法创建的对象,使用的构造函数都是Object
,所以创建的对象都是Object
这个类型,导致我们无法区分多种不同类型的对象。所以这种方法用的不多。
构造函数
我们可以创建不同的构造函数,用来专门创建不同的类对象。
构造函数的创建方式和普通函数相同,习惯上首字母大写。
普通函数直接调用,构造函数需要使用new
关键字来调用。
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function(){
alert(this.name);
};
};
var obj1 = new Person("han",27,"male");
console.log(obj1);
obj1.sayName();
在使用new
关键字调用构造函数时,构造函数会执行下面的流程:
1.立即创建一个新的对象
2.将新的对象设置为函数中的this
,可以使用this
来引用新建的对象
3.逐行执行函数中的代码
4.将新建的对象作为返回值返回
使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类,将通过一个构造函数创建的对象称为该类的实例。
如果将函数直接定义在构造函数内部,那么创建的实例每调用一次该函数,系统就会重新创建一个新的方法,这就会造成资源浪费,我们可以把该函数提出来,放到全局作用域中进行定义,然后将该函数赋值给this.sayName
,这样可以提升系统运行效率。
...
this.sayName = fun;
}
function fun(){
alert(this.name)
}
但是这样写会污染全局作用域的命名空间,并且写在外部不安全,为了解决这个问题,看下一篇《原型》。
使用instanceof可以检查一个对象是否是一个类的实例。
console.log( obj1 instanceof Person);
而Object
类是所有类的基类。
this
- 当以函数形式调用时,
this
就是window
- 当以方法调用时,谁调用
this
就是谁 - 当以构造函数的形式调用时,
this
就是新创建的那个对象。