第47题 JS易错题
. VS = 操作符优先级
let a = {n : 1};
let b = a;
a.x = a = {n: 2};
console.log(a.x)
console.log(b.x)
输出是什么呢?
答案
// undefined
// { n : 2}
作用域
var a = 0,
b = 0;
function A(a) {
A = function (b) {
console.log(a + b++)
}
console.log(a++)
}
A(1)
A(2)
```**答案**
**答案 1 4**
### 类数组的length
```js
var obj = {
"2" : 3,
"3" : 4,
"length" : 2,
"splice" : Array.prototype.splice,
"push" : Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
这段代码的执行结果?
答案
Object(4) [empty × 2, 1, 2, splice: ƒ, push: ƒ]

- 解释就是第一次使用
push,obj对象的push方法设置obj[2] = 1,obj.length++ - 解释就是第一次使用
push,obj对象的push方法设置obj[3] = 2,obj.length++ - 使用
console.log()方法输出的时候,因为obj上有length属性和splice方法,故将其作为数组输出打印 - 打印时因为数组未设置下标为0和1的值,故打印的结果就是
empty,主动获取obj[0] = undefined
非匿名自执行函数,函数名只读
var b = 10;
(function b(){
// 'use strict'
b = 20
console.log(b)
})()
输出的结果是什么?
答案
Function b
- 如标题一样,非匿名自执行函数,函数名不可以修改,严格模式下会
TypeError, - 非严格模式下,不报错,修改也没有用。
- 查找变量b时,立即执行函数会有内部作用域,会先去查找是否有b变量的声明,有的话,直接复制
- 确实发现具名函数
Function b(){}所以就拿来做b的值 - IIFE的函数内部无法进行复制(类似于const)
非匿名自执行函数2
var b = 10;
(function b(){
// 'use strict'
var b = 20
console.log(window.b)
console.log(b)
})()
输出是多少呢?
答案
10
20
// 访问b变量的时候,发现var b = 20;在当前作用域中找到了b变量,于是把b的值作为20
非匿名自执行函数3
var b = 10;
(function b(){
console.log(b)
b = 5
console.log(window.b)
var b = 20
console.log(b)
})()
输出的结果是多少呢?
变量提升
var name = 'World!';
(function () {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
在 JavaScript中, Fun 和 var 会被提升
相当于
var name = 'World!';
(function () {
var name;
if (typeof name === 'undefined') {
name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
巩固一下:
var str = 'World!';
(function (name) {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})(str);
```**答案**
> 答案:Hello World 因为name已经变成函数内局部变量
### 数组的原型是什么
```js
Array.isArray( Array.prototype )
这段代码的执行结果?
答案
- 答案:
true - 解析:
Array.prototype是一个数组 - 数组的原型是数组,对象的原型是对象,函数的原型是函数
数组比较大小
var a = [1, 2, 3],
b = [1, 2, 3],
c = [1, 2, 4]
a == b
a === b
a > c
a < c
这段代码的执行结果?
答案
- 答案:
false, false, false, true - 解析:相等(==)和全等(===)还是比较引用地址。引用类型间比较大小是按照字典序比较,就是先比第一项谁大,相同再去比第二项。
原型
var a = {}, b = Object.prototype;
[a.prototype === b, Object.getPrototypeOf(a) === b]
执行结果是多少呢
- 答案:
false, true - 解析:
Object的实例是 a,a上并没有prototype属性a的__poroto__指向的是Object.prototype,也就是Object.getPrototypeOf(a)。a的原型对象是b
原型II
function f() {}
var a = f.prototype, b = Object.getPrototypeOf(f);
a === b
这段代码的执行结果?
- 答案:false
- 解析:
- a是构造函数f的原型 :
{constructor: ƒ} - b是实例f的原型对象 :
ƒ () { [native code] }
- a是构造函数f的原型 :
函数名称
function foo() { }
var oldName = foo.name;
foo.name = "bar";
[oldName, foo.name]
代码执行结果是什么?
- 答案:
["foo", "foo"] - 解析:函数的名字不可变.
Function.length
var a = Function.length,
b = new Function().length
a === b
这段代码的执行结果是?
- 答案:
false - 解析:
- 首先new在函数带()时运算优先级和.一样所以从左向右执行
new Function()的函数长度为0
- 巩固:
function fn () {
var a = 1;
}
console.log(fn.length)
//0 fn和new Function()一样
"b" + "a" + +"a" + "a"
你认为输出是什么?
上面的表达式相当于'b'+'a'+ (+'a')+'a',因为(+'a')是NaN,所以:
'b'+'a'+ (+'a')+'a' = 'b'+'a'+ "NaN"+'a'='baNaNa'
闭包
这是一个经典JavaScript面试题
let res = new Array()
for(var i = 0; i < 10; i++){
res.push(function(){
return console.log(i)
})
}
res[0]()
res[1]()
res[2]()
期望输出的是0,1,2,实际上却不会。原因就是涉及作用域 ,怎么解决呢?
- [x] 使用let代替var,形成块级作用域
- [x] 使用bind函数。
res.push(console.log.bind(null, i))
解法还有其他的,比如使用IIFE,形成私有作用域等等做法。
又一经典闭包问题
function fun(n,o) {
console.log(o)
return {
fun:function(m){
return fun(m,n);
}
};
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
隐式转换
var a = [0];
if (a) {
console.log(a == true);
} else {
console.log("wut");
}
你们觉得答案是多少呢?
// 答案:false
再来一道?
function fn() {
return 20;
}
console.log(fn + 10); // 输出结果是多少
function fn() {
return 20;
}
fn.toString = function() {
return 10;
}
console.log(fn + 10); // 输出结果是多少?
function fn() {
return 20;
}
fn.toString = function() {
return 10;
}
fn.valueOf = function() {
return 5;
}
console.log(fn + 10); // 输出结果是多少?
一道容易被人轻视的面试题
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
let var
function foo() {
let a = b = 0;
a++;
return a;
}
foo();
typeof a; // => ???
typeof b; // => ???
上面的let a = b = 0; 等价于 window.b = 0, let a = b;
眼力题
const length = 4;
const numbers = [];
for (var i = 0; i < length; i++);{
numbers.push(i + 1);
}
numbers; // => ???
唯一需要注意的就是for语句后面带了;沙雕题
加了
;,会认为for执行完,所以指定的都是空语句,最后numbers为[5]
