前端不容忽视的小细节(学习笔记)

330 阅读3分钟

1、写出如下问题答案

console.log(a); // Uncaught ReferenceError: a is not defined

2、写出如下问题答案

if(false){
    var a = 1
}

console.log(a) // undefined

解析:
知识点: 变量提升
上面的代码等同于
var a;
if(false){
    a = 1
}
console.log(a)

3、请写出下面的答案

alert(a)
a();
var a=3;
function a(){
    alert(10)
} 
alert(a)
a=6;
a();

答案解析
1、知识点: 变量提升,函数提升 
2、函数和变量名重名,如果变量没有赋值,函数生效(函数优先级 > 变量)
上面的代码等同于

function a(){
    alert(10)
}

var a; //未赋值
alert(a);
a = 3;
a();


4、写出答案

var a = function test(param){
    test = param;
    console.log( typeof(test)) // funciton 解析 test 函数是只读的
}

a(1)
var a = function test(param){
    return 1;
}

console.log( typeof(test()) ) //Uncaught ReferenceError:

5、 写出答案

this.a = 20;
var test = {
a: 40,
init:()=> {
console.log(this.a);
function go() {
// this.a = 60;
    console.log(this.a);
}
go.prototype.a = 50;
return go; 
}
};
//var p = test.init();
//p();
new(test.init())();
变体一:
this.a = 20;
var test = {
    a: 40,
    init: function(){
        console.log(this.a); 
    }
}

test.init(); //40  this指向test

变体二:
this.a = 20;
var test = {
    a: 40,
    init: function(){
        console.log(this.a); 
    }
}

var fn = test.init;
fn() //20 this 指向window

变体三:
this.a = 20;
var test = {
    a: 40,
    init: function(){
        function go(){
            console.log(a)
        }
        
        go();
    }
}

test.init() //20 没人调用指向window

变体四:
this.a = 20;
var test = {
    a: 40,
    init: function(){
        function go(){
            console.log(a)
        }
        
        return go;
    }
}

var fn = test.init();
fn(); //20  指向window
变体五:
this.a = 20;
var test = {
    a: 40,
    init: () => {
        console.log(this.a); 
    }
}

test.init(); //20  解析:箭头函数导致this总是指向函数定义生效时所在的对象
详细请看ES6阮一峰 函数的扩展 http://es6.ruanyifeng.com/#docs/function

6、写出答案

function Test(a){
    this.a = a
}

Test.prototype.a = 20;
Test.prototype.init = function() {
    console.log(this.a)
}

var t = new Test(30);
t.init(); //30
var t1 = new Test(); //解析 new 之后 如果没有返回值 ,就会生成一个新的对象
t1.init(); //undefined 
this.a = 20;
var test = {
    a: 40,
    init: function(){
        console.log(this.a); 
    }
} //此处没有分号

(function() {
    var fn = test.init;
    fn(); // 报错  解析对象 闭包在一起 必须加分号 不然会报错
})()


this.a = 20;
var test = {
    a: 40,
    init: function(){
        console.log(this.a); 
    }
}; //!!!!注意,这里有个一个分号

(function() {
    var fn = test.init;
    fn(); //20
})()

7、说出下下面的答案

this.test = 11;
var s =  {
	a:function() {
		console.log(1+this.test)
	},
	b(){ //ES6 函数简写
		console.log(this.test)
	}
}

var f = s.a.bind(this);
new f(); // NaN 解析 new 之后 如果没有返回值 ,就会生成一个新的对象 指向函数a a中没有this.test 所有返回NaN 

var p = s.b.bind(this);
new p(); // VM360:15 Uncaught TypeError: p is not a constructor 解析es6 简单函数 不允许 new

8 写出答案

function Test(name) {
    if (name) this.name = name;
}

Test.prototype.name = 'junjun';

console.log((new Test().name)) // junjun   解析 t = new Test(); t.__proto__ = Test.prototype 所以会从原型链上去查找

9、写出答案

var a = 50;
{
    a = 20; //Uncaught ReferenceError: Cannot access 'a' before initialization 
    解析 ES6 let和 const 命令章节 暂时性死区 TDZ 
    let a = 10;
}

10、写出答案

function test(m) {
    m = {v:5}
}
var m = {k: 30};
test(m);
alert(m.v); //undefined 解析 高级程序设计三传递参数 当函数内部重写m 这个变脸的引用就变成了局部对象了,而这个局部对象会在函数执行完毕,立即销毁


总结:

  • 1、函数提升 > 变量提升
  • 2、函数名和变量名相同 如果变量未赋值 函数 > 变量
  • 3、var s = function Test() {} 函数只能,只能内部调用
  • 4、this 指向调用的位置 没人调用 指向window
  • 5、ES6简单的函数 不支持new
  • 6、new this 的指向
  • 7、对象 闭包在一起 必须加分号
  • 8、暂时性死区