JS中被自己忽略掉的一些东西 - 2

6.void

在使用立即执行的函数表达式时,可以利用 void 运算符让 JavaScript 引擎把一个function关键字识别成函数表达式而不是函数声明(语句)。

void function(){
    console.log(1);
}();
//这里使用了 void 关键字,将后面的 function 当成了一个函数表达式,从而在后面加上“()”就可以直接运行了。

7.yield

yield 关键字用来暂停和恢复一个生成器函数

function* loop() {
    for (var i = 0; i < 5; i++) {
        yield i;
    }
}

var l = loop();
console.log(l.next());//{value: 0, done: false}
console.log(l.next());//{value: 1, done: false}
console.log(l.next());//{value: 2, done: false}
console.log(l.next());//{value: 3, done: false}
console.log(l.next());//{value: 4, done: false}
console.log(l.next());//{value: undefined, done: true}

还可以向 next(param) 方法传参,传递的参数会当成上一个 next 的运行结果。

function* loop(base) {
    yield base;
    base = yield base + 1;
    yield base;
    return "aa";
}

var l = loop(5);
console.log(l.next());//{value: 5, done: false}
console.log(l.next());//{value: 6, done: false}
console.log(l.next(10));//{value: 10, done: false}
console.log(l.next());//{value: "aa", done: true}

8.bind

调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的。

function f(){
  return this.a;
}

//this被固定到了传入的对象上
var g = f.bind({a:"1"}); // g 是一个新函数,this 被绑定了
console.log(g()); // 1

var h = g.bind({a:'2'}); //bind只生效一次!g 被绑定过,不能再次绑定
console.log(h()); // 1

var y = f.bind({a:'3'}); //这样是可以的,f 并未被绑定
console.log(y()); // 3

9.this

箭头函数的 this 在创建的时候,就被设置为其外层的执行上下文,后面不会改变,即使使用 call 或是 apply.

var x = {y: function() {return () => this}};

let y_f = x.y();
console.log(y_f() == x); // true
console.log(y_f.call({}) == x); // true

//但是注意,如果你只是引用 y 的方法,而没有调用它(this是在函数调用过程中设置的)
//那么调用箭头函数后,this 指向 window,因为它从 y 继承了this
console.log(x.y()() == x); // false
console.log(x.y()() == window); // true 

10.freeze

使用 const 声明一个变量时,若声明的是一个对象,只是指向这个对象的地址不可以变更,但对象本身还是可以被修改的。

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

使用 const 声明一个数组,也是跟对象一样:

const a = [];
a.push('Hello'); // 可执行
a.length = 0;    // 可执行
a = ['Dave'];    // 报错

如果真的想将对象冻结,应该使用Object.freeze方法。

const foo = Object.freeze({});

// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;

上面代码中,常量foo指向一个冻结的对象,所以添加新属性不起作用,严格模式时还会报错。

除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};

猜你喜欢

转载自blog.csdn.net/hsl0530hsl/article/details/79153639
今日推荐