面试之ES6

面试的过程中提到了symbol,很悲剧我答得超级差,所以晚上回来整理下,遇到不会的就要立刻补救!

以后关于ES6的我也都整理在此~

Symbol

1.symbol独一无二,用于避免命名冲突,所以我们可以用于对象的属性名。

之前提过for in可以遍历到原型上的方法和属性;Object.keys(obj)返回的不包括原型上的方法和属性。for-in却不会遍历到对象的symbol键,Object.keys(obj)也是,这么一想它比原型还牛掰惊讶

2.symbol不能被隐式转换为字符串

        var sym = Symbol("<3");//注意不能用new,虽然Symbol是构造函数
        console.log(sym);//Symbol(<3)
        console.log("Symbol:"+sym);//Uncaught TypeError: Cannot convert a Symbol value to a string

但可以通过显式转换String(sym)或sym.toString()转换为字符串。

对象解构赋值

1.对象解构什么时候默认值起作用?

当属性值严格等于undefined(比如不写或直接赋undefined)

var { message: msg = "You Are A Person!" } = {};
consle.log(msg); //"You Are A Person!"

var { x = 3 } = { x: undefined };
console.log(x); //3

null的情况下不算等于undefined哦~

var { y = 3 } = { y: null };
console.log(y);//null

2.已声明过的变量如何解构赋值?

最简单的,可以在解构赋值的时候进行声明:

var {x:x0,y=2}={x:1};
console.log(x0,y);//1,2

那已经声明过的变量可以也这么使用吗?

var x,y;
{x:xo,y=2}={x:1};//Uncaught SyntaxError: Unexpected token =
console.log(xo,y);

可以发现报错啦!此处将{x:xo,y=2}理解为一段代码块;事先已经声明过的变量,如果再想解构赋值,需要套一层()

var x,y;
({x:xo,y=2}={x:1});
console.log(xo,y);//1,2

上一道新鲜热乎的题:

let x, { x: y = 1 } = { x }; y;

A、 undefined
B、 1
C、 { x: 1 }
D、 Error

不要被迷惑了,这不是已经声明过的变量再进行解构赋值;而是会先定义x为undefined,接着默认值起作用,y还是等于1。

Class

1.类的类型是函数,类指向的是构造函数

上面两句话可以分别用下面的代码表示

class Test{

}
console.log(typeof Test);//function
console.log(Test === Test.prototype.constructor);//true

你肯定奇怪了,我没有写constructor,它是哪来的呢?

constructor是默认方法,使用new定义实例对象时自动调用constructor,并传入所需参数,执行完会返回实例对象。如果没有定义constructor,默认添加一个空的constructor进去。

2.定义类分为类声明&类表达式

类声明

class Test{

}

类表达式(class后面的类名只能在类的内部进行使用,在外面用就报错)

var prepare = class Test{
    constructor(){
        console.log(Test);//可以打印出来Test这个类
    }
}
new prepare();
new Test()//Test is not defined;

立即执行的类需要在类前加上new

const p = new class {
    constructor(name,age){
        console.log(name,age);
    }
}("job",30)

3.class没有函数声明提升

//-----函数声明-------
//定义前可以先使用,因为函数声明提升的缘故,调用合法。
func();
function func(){}

//-----定义类---------------
new StdInfo();  //报错,StdInfo is not defined
class StdInfo{}

4.如果子类有constructor函数,必须要用super关键字把this拿到手

        class a{
            constructor(cloth,cost){
                this.cloth = cloth,
                this.cost = cost
            }
            tellMe(){
                console.log(this.cloth+"的价格是"+this.cost+"便士");
            }
        }
        var shirt = new a("衬衫",15);
        shirt.tellMe();
        class b extends a{
            constructor(cloth,cost,pos){
                super(cloth,cost);//子类没有自己的this,是继承父类的this,这一步让子类拥有自己的this
                this.pos = pos;
            }
            tellMe(){
                console.log(this.pos+this.cloth+"的价格是"+this.cost+"便士");
            }
        }
        var pants = new b("裤子",23,"这件");
        pants.tellMe();

出一个比较刁钻的题目吧,不仅结合了extends还有对于括号执行单个/多个表达式只返回最后一个表达式的值~

typeof (new (class F extends (String, Array) { })).substring

A、 "function"
B、 "object"
C、 "undefined"
D、 Error

括号里的内容被当做表达式来看
(String, Array) //Array,返回最后一个值
(class F extends Array); //class F继承成Array
(new (class F extends Array)); //创建一个F的实例
(new (class F extends (String, Array) { })).substring; //取实例的substring方法,由于没有继承String,Array没有substring方法,那么返回值为undefined
typeof (new (class F extends (String, Array) { })).substring; //对undefined取typeof

5.不支持定义私有属性和私有方法

箭头函数

1.this永远指向所在上下文环境的this

var obj ={
    a: 233,
    b: function(){
        console.log(this,this.a);
    },
    c: function(){
        return ()=>{
            console.log(this,this.a);
        }
    },
    d: ()=>{
        console.log(this,this.a);
    }
}
var a = 666;
obj.b();//obj 233
obj.c()();//obj 233
var obj_b = obj.b;
obj_b();//Window 666
obj.d();//Window 666

obj.c方法中return的箭头捕获的是function(){ }这个环境的this,所以指向的是obj;

obj.d方法中的箭头捕获的是obj{ }这个对象的环境,所以指向的是window。

2.call和apply没有用

obj.d();//Window 666
obj.d.call(obj);//Window 666
obj.d.apply(obj);//Window 666
obj.b();//obj 233
obj.b.call(window);//Window 666

3.箭头函数不能当做Generator函数,不能使用yield关键字

猜你喜欢

转载自blog.csdn.net/weixin_40322503/article/details/80010984