var name = "World!";
(function () {
var name;
if (typeof name === 'undefined') {
name = 'Jack';
console.log('Goodbye' + name);
} else {
console.log('hello' + name);
}
})();
变量声明提升,JS代码分为存储模块和执行模块。当匿名自调用函数中, 有该变量(和全局变量同名的变量)时,在自身查找,有变量查看是否赋值,赋值直接输出,没有就找全局。因为js是单线程执行var name
当前没有赋值,所以类型为undefined
。
结果:Goodbye Jack
语句var arr=[a,b,c,d];
执行后,数组arr中每项都是一个整数,下面得到其中最大整数语句正确的是哪几项?(多选)
A. Math.max(arr)
B. Math.max(arr[0], arr[1], arr[2], arr[3])
C. Math.max.call(Math, arr[0], arr[1], arr[2], arr[3])
D. Math.max.apply(Math,arr)
Math.max(args...)
传入参数是任意数量的值
A. 错误,不能传入数组
B. 正确
C. 正确,call()可以传入任意多个参数
D. 正确,apply()第二个参数以数组形式传递
结果:B、C、D
var A = {n: 4399};
var B = function(){this.n = 9999};
var C = function(){var n = 8888};
B.prototype = A;
C.prototype = A;
var b = new B();
var c = new C();
A.n++
console.log(b.n);
console.log(c.n);
主要考察的是原型链,先查看自身是否有,没有找原型,原型也没有找Object,再找不到就是undefined。
1.console.log(b.n);
:
在查找b.n
是首先查找 b 对象自身有没有 n 属性,如果没有会去原型(prototype)上查找,当执行var b = new B()
时,函数内部this.n=9999
(此时this指向 b) 返回b对象,b对象有自身的n属性,所以返回 9999。
2.console.log(c.n);
:
同理,当执行var c = new C()
时,c对象没有自身的n属性,向上查找,找到原型 (prototype)上的 n 属性,因为 A.n++
(此时对象A中的n为4400), 所以返回4400。
结果:9999、4400
var arr=[{a:1},{}];
arr.forEach(function(item,index){
item.b=index;
});
console.log(arr);
forEach()
方法是对数组中的每一项运行给定函数,回调函数的参数item
为数组当前项,index
为当前索引。
这道题就是把数组每一项添加属性 b,并且属性 b 的值为当前项的数组索引值。
然后,forEach()
方法没有返回值,所以不能将arr.foreach()
像其他数组迭代方法那样赋值给某一个变量。
结果:[{a:1,b:0},{b:1}]
var sum = new Function('a','b','return a+b')
var sum = function(a,b){ return a+b }
function sum(a,b){ return a+b }
js函数定义的几种方式如下表:
定义方法 | 代码块 |
---|---|
函数声明 | function sum(a,b){ return a+b } |
函数表达式 | var sum = function(a,b){ return a+b } |
构造函数 | var sum = new Function(‘a’,‘b’,‘return a+b’) //不推荐使用,影响函数解析性能 |
结果:构造函数、函数表达式、函数声明
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log(this.foo);
console.log(self.foo);
(function() {
console.log(this.foo);
console.log(self.foo);
}());
}
};
myObject.func();
这道理的关键就在于,方法/函数是由谁调用的,那么其内部的this
就指向谁
首先func
是由myObject
调用的,this
指向myObject
。
又因为var self = this;
所以self
指向myObject
。
这个立即执行匿名函数表达式是由window调用的,this
指向window 。
立即执行匿名函数的作用域处于myObject.func
的作用域中,在这个作用域找不到self
变量,沿着作用域链向上查找self
变量,找到了指向 myObject
对象的self
。
所处域 | this指向 |
---|---|
window | window |
普通函数 | window |
构造函数 | 指向类的实例对象 |
定时器 | window |
自调用函数 | window |
结果:bar bar undefined bar
var x = new Boolean(false);
if (x) {
alert('hi');
}
var y = Boolean(0);
if (y) {
alert('hello');
}
这道题考察了JS的类型转换,这里的var x
是一个对象,任何对象转为布尔值,都为得到true。
题目的第二部分,一定要注意 y = Boolean(0)
,而不是 y = new Boolean(0)
。这两个有很大区别,用new
调用构造函数会新建一个布尔对象,此处没有加new
,进行的是显示类型转换,所以就是false
结果:hi
var value = 0;
console.log(value != '0' ? 'nonzero' : 'zero');
console.log('Value is ' + (value != '0') ? 'nonzero' : 'zero');
这道题考察的是第二个console.log
中运算符的优先级,加号优先级高于三目运算,低于括号。 所以括号中无论真假,加上前边的字符串都为 true,三目运算为true是输出nonzero
结果:zero、nonzero
如有问题,请在评论中指出,我们互相学习,一起进步!