这是我参与2022首次更文挑战的第2天,活动详情查看:链接
一,什么是this?
浏览器在调用函数时,每次都会向函数内部传递一个隐含参数,就是 this , this指向是一个对象。
这个对象我们称它为函数执行的上下文对象,根据函数调用方式不同,this会指向不同的对象。
function fun(a,b){
console.log(this.name)
}
var obj = {
name:'张三',
sayName: fun
}
obj.sayName == fun ?? //true
我们可以这样去判断this的指向
- 以函数形式调用,this永远都是window
- 以方法形式调用,this就是调用方法的对象(如上例子代码,调用obj.sayName,得到的this为该对象)
- 当以构造函数形式调用,this就是新创建的那个对象。
二,看个例子
var name = '全局的'
function fun(){
console.log(this.name)
}
var obj = {
name:'张三',
age:19,
sayName:fun
}
var obj2 = {
name:'李四',
age:12,
sayName:fun
}
console.log(obj.sayName())
console.log(obj2.sayName())
结果
\
三,工厂模式创造对象
使用工厂模式创建对象,通过该方法生成大批量对象
function createPerson(name,age,gender){
var obj = new Object()
obj.name = name
obj.age = age
obj.gender = gender
return obj
}
var obj = createPerson('张三',19,'男')
使用工厂模式创建的对象,使用的构造函数都是 Object , 所以创建的对象都是object类型,可以通过打印查看。
控制台会打印 #[Object,Object]
这样会导致我们无法区别出多种不同的类型。
四,构造函数
什么是构造函数?像 new Object(), new Array() ... 等 JavaScript为我们提供的构造函数,创建一个构造函数,与创建普通函数无任何差别,不同的是
构造函数习惯首字母大写 ,调用方式不同:普通函数直接调用,而构造函数需要使用new关键字来调用
function Person(name,age,gender){
this.name = name
this.age = age
this.gender = gender
this.sayName = function(){
console.log('我是:'+ this.name)
}
}
var per = new Person('张三',12,'男')
可以看到,使用构造函数创建的对象,constructor 是这个构造函数本身。
控制台打印 #[Person,Object]
#构造函数执行的流程
- 立刻创建一个新的对象
- 将新建的对象设置为函数this,在构造函数中使用
- 执行函数中的代码,this来引用新建的对象
- 将新建的对象作为返回值返回
使用同一个构造函数创建的对象,我们称为类对象,也将一个构造函数称为一个类。
我们将通过一个构造哈函数创建的对象,称为该类的实例。
#使用instanceof 检查一个对象是否是某个类的实例
语法:对象 instanceof 构造函数
如:
console.log(per instanceof Person) //true
console.log(per instanceof Object) //true
所有的对象都是Object的后代,所以使用instanceof 检查对象和object时,都会返回true。
五,外部创建构造函数的方法
在上面的Person构造函数中,为每个对象都添加一个sayName方法,目前,我们的方法都是在构造函数内部创建的,也就是说,构造函数每执行一次就会新创建一个新的sayName 方法。
也就是所有的实例的方法都是唯一的。
这样就会导致够着函数每执行一次,就会创建对应新的方法,也就是构造函数内部方法都会重新创建。这是完全没有必要的,完全可以使所有的对象共同调用一个方法,如:
//将sayName 方法在全局作用域中定义
function sayName(){
alert('我是:'+ this.name)
}
function Person(name,age,gender){
this.name = name
this.age = age
this.gender = gender
this.sayName = sayName
}
但有个问题,在全局中定义了函数,会污染全局作用域命名空间。而且定义在全局作用域中也很不安全。
下一章我们讲解通过在原型上定义去处理这一问题。