1 function test (x, y, z) {
console.log(test.length)
console.log(arguments.length)
console.log(arguments.callee === test)
console.log(arguments[2])
}
test(10,20)
答案:3 2 true undefined
解析:
test.length是返回的函数的形参个数,所以为3;
arguments.length返回的是函数调用时的实参个数,所以为2;
arguments.callee:初始值就是正被执行的 Function 对象,用于在函数内部调用自身,arguments对象本身是个由函数调用时传入的实参组成的伪数组,访问单个参数的方式与访问数组元素的方式相同。
只传入了两个参数,自然为undefined.
2 var a = 10
a.pro = 10
console.log(a.pro + a)
var s = 'hello'
s.pro='world'
console.log(s.pro+s)
答案:NaN undefinedhello
解析:JavaScript引擎内部在处理对某个基本类型 a进行形如a.pro的操作时,会在内部临时创建一个对应的包装类型(对数字类型来说就是Number类型)的临时对象,并把对基本类型的操作代理到对这个临时对象身上,使得对基本类型的属性访问看起来像对象一样。但是在操作完成后,临时对象就销毁了,下次再访问时,会重新建立临时对象,当然就会返回undefined了
3
var f =1
if(!f) {
var a =10
}
function fn() {
var b =20
c = 30
}
fn()
console.log(a)
console.log(c)
console.log(b)
答案:undefined 30 报错:b is not defined
解析:
1、没有用var声明的是全局变量,即便在函数内部;
2、只有在function内部新声明的才是局部变量,在if,while,for等声明的变量其实是全局变量(除非本身在function内部)
3、因为变量提升,虽然if块的内容没执行,但是预解析阶段会执行var a,只是没有赋值而已,因此打印a是undefined而打印b会报错
4
var length = 10
function fn () {
console.log(this.length)
}
var obj = {
length: 5,
method: function(fn) {
fn()
arguments[0]();
}
}
obj.method(fn,1)
答案:10,2,第一次输出10应该没有什么异议,这里的this指向window,第二个调用arguments[0]()相当于执行arguments调用方法,this指向arguments,而这里传了两个参数,故输出arguments长度为2。
5 function fn(a) {
console.log(a)
var a = 2
function a() {}
console.log(a)
}
fn(1)
答案:f a() { } 2
解析:我们知道预解析阶段,变量声明和函数声明会提前,且变量名和函数名同名时,函数优先级高于变量,会覆盖变量,因此第一个输出的是f a(){ },继续执行,会执行a=2,再输出的时候就会输出2,不理解的同学百度一下变量提升和函数提升
6 已知数组,编写一个程序将数组便情话并且去掉其中的重复数字,然后升序排列
[[11,22,22],[13,14,15,15],[16,17,18,19,[11,12,[12,13,[14]]]],12]
7 实现一个函数add,满足以下结果
add(1) // 1
add(1,2) // 3
add(1)(2) // 3
add(1,2)(3,4) // 10
add(1)(2)(3) //6
function add () {
const arg = [...arguments]
function sum () {
arg.push(...arguments)
return sum
}
sum.toString = function () {
return arg.reduce((x, y) => {
return x + y
})
}
return sum
}
console.log(add(1))
console.log(add(1, 2))
console.log(add(1, 2)(3, 4)(5,6))
8 看代码
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
1 访问的是Foo函数上存储的静态属性
2 函数表达式覆盖函数声明,因此调用的是覆盖后的getName
3 先执行了Foo(),此时返回window,并且函数里getName没有var 所以覆盖了全局的 因此是1
4 等同于window.getName 4
5 点运算符优选与new, 执行为 new (Foo.getName)()
6 执行顺序为 (new Foo()).getName() (new Foo()) 返回Foo一个实例
7 执行顺序为 new ((new Foo()).getName)() 先初始化Foo实例 然后将其原型上的getName 作为构造函数再次new
9 读代码
var x = 1
if (function f() {
}) {
x += typeof f
}
console.log(x)
输出结果是
1undefined
解析:条件判断为假的情况有:0,false,'',null,undefined,未定义对象。函数声明写在运算符中,其为true,但放在运算符中的函数声明在执行阶段是找不到的。另外,对未声明的变量执行typeOf不会报错,会返回undefined