首先定义一个Test函数:
function Test() {
console.log(this) // => window
}
Test()
这里先解释下this
我们在全局环境下调用了Test函数,然后在函数内部打印了this,众所周知,函数内部的this指向的是调用函数的对象,这里我们在全局调用了Test,所以打印出来的this就是window
'use strict' // 开启严格模式
// 注意:在严格模式下
// 函数的内部不允许this指向window
// 所以在严格模式下这里打印的this会是undefined
function Test() {
console.log(this) // => undefined
}
// 但是有一种特殊情况需要注意
// setTimeout是window的方法
// setTimeout 在调用传入函数的时候
// 如果这个函数没有指定了的 this
// 那么它会做一个隐式的操作-->自动地注入全局上下文window。
setTimeout(function(){
console.log(this) // => window
},0);
回归正题
接下来我们在Test函数通过this和定义变量的方式添加了一些基本数据类型和引用数据类型
注意代码中的注释!
function Test() {
this.name = 'yy';
this.tObj = { t: 'Test Object' }
let str = 'this is a String'
let num = 123
const obj = { k: 'this is a Object' };
const arr = ['a1', 'a2'];
}
// 直接调用Test()
const funT = Test()
console.log(funT) // => undefined
// 直接调用的函数如果内部没有return,打印它就没有任何意义,也拿不到内部的属性和变量
// 直接调用的方式如果内部存在return,那funT的值就为return的返回值,这里就不再举例了
// 所以直接调用的方式就到此结束,接下来我们让我们来看看new的方式
// new Test() (构造函数)
const newT = new Test()
console.log(newT) // => Test {name: "yy", tObj: {…}} //返回值是一个对象
console.log(newT.name) // => yy
console.log(newT.tObj) // => {t: "Test Object"}
console.log(newT.str) // => undefined
console.log(newT.num) // => undefined
console.log(newT.arr) // => undefined
console.log(newT.obj) // => undefined
// new的方式可以看到,返回值newT是一个对象
// 我们可以通过这个对象拿到Test函数中通过this定义的name和tObj
// 但是拿不到其中的变量
这样我们就能看出直接调用Test和new Test方法的一些区别了
但是新的问题来了
如果我们在Test函数中新增一个return语句,这个时候再去new Test会发生什么呢?
function Test() {
this.name = 'yy';
this.tObj = { t: 'Test Object' }
let str = 'this is a String'
let num = 123
const obj = { k: 'this is a Object' };
const arr = ['a1', 'a2'];
// return this.name
// return this.tObj
// return str
// return num
// return obj
// return arr
}
// new Test()
const newT = new Test()
console.log(newT)
// 经过测试-当函数Test中return不同内容时console.log(newT)打印的内容如下
// return this.name // => {name: 'yy'}
// return this.tObj // => {t: "Test Object"}
// return str // => {name: 'yy'}
// return num // => {name: 'yy'}
// return obj // => {k: "this is a Object"}
// return arr // => ["a1", "a2"]
经过测试我们可以看出:
如函数内部return的值是一个基本数据类型,new函数的值就是该函数的实例对象,这个实例对象中只包含函数中通过this定义的属性
如函数内部return的值是一个引用数据类型,new函数的值就等于return的值,这种模式也被称为寄生模式。
注:new一个函数时被称为构造函数,函数名通常首字母大写,直接调用一个函数时函数名首字母通常应该小写。