为何JS中同一段console.log在函数调用与实例化时结果不同?
为什么函数直接调用和实例化时console.log输出不同?
嘿,这个问题戳中了JavaScript函数调用的核心知识点——this的绑定规则!咱们一步步拆解清楚:
先看两种调用方式的本质区别
假设你的代码大概是这样的:
function MyFunction() { console.log(this); } // 直接调用函数 MyFunction(); // 实例化调用 new MyFunction();
这两种调用方式下,console.log(this)的输出完全不同:直接调用时输出浏览器的window对象,实例化时输出MyFunction的实例对象。
1. 直接调用函数:默认绑定全局对象
当你把函数当作普通函数直接调用时(不是作为对象方法、不是用new/call/apply),JavaScript的默认绑定规则会生效:
- 非严格模式下,
this会绑定到全局上下文(浏览器里就是window,Node.js里是global) - 严格模式下,
this会是undefined
这就是为什么你看到函数内部好像用了window的作用域——其实不是作用域本身,是this指向了全局对象,所以如果在函数里访问this.xxx,就相当于访问window.xxx。
2. 用new实例化:this绑定到新实例
当你用new操作符调用函数时,JavaScript会自动完成这几个步骤:
- 创建一个全新的空对象
- 把这个新对象的原型链链接到函数的
prototype属性 - 把函数内部的
this绑定到这个新创建的对象 - 如果函数没有显式返回一个对象,就自动返回这个新对象
所以这时候console.log(this)输出的是这个新实例,而不是全局对象。
关于“函数自身作用域”的误区
你提到的“函数内部的作用域为何会使用window作用域”其实是混淆了作用域链和**this指向**:
- 函数自身的作用域是指函数内部声明的变量、参数所在的环境,这些变量只会在函数内部(和嵌套函数)可见,和
window没关系 this是执行上下文的一部分,它的指向完全由函数的调用方式决定,和函数定义的位置无关
举个例子验证:
function MyFunction() { const innerVar = "我在函数作用域里"; console.log(innerVar); // 正常输出"我在函数作用域里",和window无关 console.log(this); // 这里的this指向由调用方式决定 }
不管是直接调用还是实例化,innerVar都能正常访问,这就是函数自身作用域的体现;而this的指向才是两种调用方式的差异点。
内容的提问来源于stack exchange,提问作者Deadpool
相关产品推荐
相关产品推荐

