原稿:语雀 · JS 基础题目 · 原目录:面向面经学习 › JS 基础题目
作用域
var temp = 1;
function test() {
temp = 10;
return;
function temp() {}
}
test();
console.log(temp);
![]() | 结果为1,因为在 test() 中的函数声明会被提升,相当于在函数作用域中有一个局部变量 temp,之后执行 temp=10 是重新赋值这个局部变量,没有修改全局作用域的 temp; 拓展:当注释掉 function temp() {} ,会输出 10,因为在函数内定义变量时省略 var 时会在全局上下文中创建一个全局变量 |
作用域
function Foo() {
getName = function () {
console.log(1);
};
return this;
};
Foo.getName = function () {
console.log(2);
};
Foo.prototype.getName = function () {
console.log(3);
};
var getName = function () {
console.log(4);
};
function getName() {
console.log(5);
};
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
// 结果
//
//
//
//2 4 1 1 2 3 3
- 第三句:典型的作用域污染,Foo()执行中,getName 未使用 var 声明,因此优先沿作用域链寻找,并在全局作用域中找到,这里污染了全局作用域中的 getName
注意执行优先级“成员访问优先级 = new 有参构造 > new 无参构造”,new Foo 等同于 new Foo(),前者是无参构造,后者是有参构造:
- new Foo.getName():相当于 new(Foo.getName())
- new Foo().getName():相当于 (new Foo()).getName()
- new new Foo().getName():相当于 new ((new Foo()).getName())
var F = function() {};
Object.prototype.a = function() {
console.log('a');
};
Function.prototype.b = function() {
console.log('b');
};
var f = new F();
f.a();
f.b();
F.a();
F.b();
//结果: a TypeError: f.b is not a function a b
- 在对象 f 上寻找属性 a 未果;沿原型链进入 F.prototype,后者是一个 Object 实例,寻找属性 a 依旧未果;沿原型链进入 Object.prototye,找到并调用
- 在对象 f 上寻找属性 b 未果;在整个原型链上都无法找到属性 b,抛出错误
- 在对象 F 上寻找属性 a 未果;沿原型链进入 Function.prototype,后者是一个 Object 实例,寻找属性 a 依旧未果;沿原型链进入 Object.prototye,找到并调用
- 在对象 F 上寻找属性 b 未果;沿原型链进入 Function.prototype,找到并调用 b
原型链
function Person(name) {this.name = name;}Person.prototype.print = function() {return this.name;};Person('abc');const a = new Person('abc').print.call({});console.log(a);const fn = () => {this.x = 'z';};const b = {x: 'y'};fn.call(b);console.log(b);// undefined// {x: 'y'}
- new Person(‘abc’).print.call({}):实际上等于 person.print.call({}),显式绑定>隐式绑定
- fn.call(b):箭头函数没有 this,不存在修改绑定的说法,也不能修改箭头函数定义位置作用域的 this
原型链
var a= function () { this.b =3; }var c = new a();a.protorype.b = 9;var b = 7;a();console.log(b);console.log(c.b);// 3 3
相信自己哈,c 上确实在对象和原型上都存在 b 属性
原型链
Function.prototype.a = () => alert(1);
Object.prototype.b = () => alert(2);
function A() {};
var a = new A();
a.a();
a.b();
// 报错 Uncaught TypeError: a.a is not a function
作用域
var x = 10;
function fn(){
console.log(x);
}
function show(f){
var x = 20;
(function(){
f();
})()
}
show(fn);
// 打印10,因为fn执行时,外层作用域直接是window
