function foo(a,b){
this.val = a+b;
}
var bar = foo.bind(null, ‘p1’);
var baz = new bar(‘p2’);
console.log(baz.val);
分析
–
bind函数的第一个参数为null代表作用域不变,后面的不定参数将会和函数本身的参数按次序进行绑定,绑定之后执行函数只能从未绑定的参数开始传值。
结果
–
p1p2
自执行函数
=====
function foo(){
console.log(this.a);
}
var a = 2;
var o = {a:3,foo:foo};
var p = {a:4};
(p.foo=o.foo)();
分析
–
经常可以看到这样的代码
(function(){
//…
})()
这种代码通常是创建一个立即执行的函数同时避免污染全局变量。
很少有人去关注赋值语句执行之后会返回什么结果,其实就是返回当前值。也就是说当括号内执行完赋值之后,返回的是o对象中的foo函数。函数的执行环境中有一个a对象,嗯,就是它了~
答案
–
2
变量属性
====
var a = [];
a[0] = 1;
a[‘foobar’] = 2;
console.log(a.length);
console.log(a.foobar);
分析
–
《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 当一个变量被声明后,扩充其属性并不会改变原数据类型。
结果
–
1
2
精度问题
====
var a = ‘foo’;
a[1] = ‘O’;
console.log(0.1+0.2==0.3||a);
分析
–
当操作小数时请小心,js的小数计算并不精确,所以上面的判断是false。
字符串变量是常量。
结果
–
foo
命名提升
====
foo();
var foo = 0;
function foo(){
console.log(1);
}
foo = function(){
console.log(2);
};
分析
–
声明的变量和命名函数都会被提升到代码的最前面,只不过声明的变量的赋值语句在代码中的位置不变。所以上面这段代码应该被理解为:
var foo;
function foo(){
console.log(1);
}
foo();
foo = 0;
foo = function(){
console.log(2);
};
结果
–
1
思考
–
foo();
var foo = 0;
function foo(){
console.log(1);
}
foo();
foo = function(){
console.log(2);
};
foo();
上面代码的结果:
1
报错
作用域
===
foo();
var a = true;
if(a){
function foo(){
console.log(‘a’);
}
} else {
function foo(){
console.log(‘b’);
}
}
分析
–
javascript并不是以代码段为作用域,而是以函数。
再根据命名提升的原则,所以这段代码应该是这样的:
function foo(){
console.log(‘a’);
}
function foo(){
console.log(‘b’);
}
foo();
var a = true;
if(a){
} else {
}
结果
–
b
闭包陷阱
====
for(var i=1;i<=5;i++){
setTimeout(function(){
console.log(i);
}, i*1000);
}
分析
–
闭包有个重要的作用就是,在内层函数引用外层函数定义的变量时,外层函数的变量不会被会被持久化。
这里有个隐藏陷阱就是for循环结束之后i仍然自增了1。
结果
–
6
6