美文网首页
js中的this

js中的this

作者: Victor细节 | 来源:发表于2017-01-05 14:02 被阅读0次
    // 默认绑定
    // 在没有其他规则使用时的默认绑定
    // function foo(){
    //  console.log(this.a);
    // }
    // var a = 2;
    // foo();
    
    // 隐含绑定
    // 调用点是否为一个环境对象,也叫作拥有者或者容器
    // function foo(){
    //  console.log( this.a );
    // };
    // var obj = {
    //  a: 2,
    //  b: 3,
    //  fooo: foo,
    // };
    // obj.fooo();
    // foo()被声明后作为引用属性添加到obj上,被obj拥有或者包含,所以this指代的是obj
    
    
    // 隐含的丢失
    // 隐含绑定丢失了他的绑定,这就意味着它要退回到默认绑定
    // function foo() {
    //  console.log(this.a);
    // };
    // var obj = {
    //  a: 2,
    //  fooo: foo,
    // };
    // var bar = obj.fooo;
    // var a = 3;
    // bar();
    
    // 接下来我们考虑一下传递一个回调函数
    // function foo(){
    //  console.log(this.a);
    // };
    // function doFoo(fn){
    //  fn();
    // };
    // var obj = {
    //  a: 2,
    //  fooo: foo,
    // };
    // var a = 3;
    
    // doFoo(obj.fooo);
    
    // 明确绑定
    // 隐含绑定: 我们不得不改变目标对象使它自身包含一个对函数的引用,而后使用这个函数引用属性来间接的,将this绑定到这个对象上。
    // 明确绑定: 我们强制一个函数调用使用某个特定的对象作为this绑定
    
    // function foo(){
    //  console.log(this.a);
    // };
    // var obj = {
    //  a: 2,
    // };
    // foo.call( obj );
    
    // 当然我们也可以传递原始的类型值(string boolean number),这个类型值会被包装在他的对象类型中,new String() new Number()...
    
    // function sum(){
    //  // console.log(this+2);  chai boxing
    //  console.log(this); //boxing
    // };
    // sum.call(5);
    
    
    // 硬绑定
    // 有时候,单独依靠明确绑定仍然不能为我们先前提到的问题提供解决方案,也就是函数丢失原本的this绑定,或者被第三方框架覆盖,等问题。
    
    // function foo(){
    //  console.log(this.a);
    // };
    // var obj = {
    //  a: 2,
    // };
    // var bar = function(){
    //  foo.call( obj );
    // };
    // var a = 3;
    // bar();
    // bar.call(window);//不会被覆盖
    
    
    // 用硬绑定将一个函数包装起来的最典型的方法,是为所有传入的参数和传出的返回值创建一个通道
    
    // function foo(something){
    //  console.log(this.a , something);
    //  return this.a + something;
    // };
    // var obj = {
    //  a: 2,
    // };
    // var bar = function(){
    //  return foo.apply( obj,arguments );
    // };
    // var b = bar( 3 );
    // console.log( b );
    
    // 由于硬绑定是一个非常常用的模式,它已作为ES5中的內建工具提供:
    // Function.prototype.bind
    
    // 如下使用
    // function foo(something){
    //  console.log(this.a,something);
    //  return this.a + something;
    // };
    // var obj = {
    //  a: 2,
    // };
    // var bar = foo.bind(obj);
    // var b = bar( 3 );
    // console.log( b );
    
    // new 绑定  
    // js中构造器的定义:构造器仅仅是一个函数,它们偶然的被前置的new操作符调用,它们不依附于类,它们也不初始化类,它们本质上只是一般的函数,在被使用new来调用时改变了行为。
    
    // 当在函数前面被加入new调用时,也就是构造器调用时,下面这些事情会自动完成
    // 1.一个全新的对象会凭空创建 
    // 2.这个新构建的对象会被接入原型链(prototype-linked)
    // 3.这个新构建的对象被设置为函数调用的this绑定
    // 4.除非函数返回一个它自己的其他对象,这个被new调用的函数将自动返回这个新构建的对象。
    
    
    // 绑定的顺序
    // 函数中的this绑定规则的优先级
    
    // function foo() {
    //     console.log( this.a );
    // }
    
    // var obj1 = {
    //     a: 2,
    //     foo: foo
    // };
    
    // var obj2 = {
    //     a: 3,
    //     foo: foo
    // };
    
    // obj1.foo(); // 2
    // obj2.foo(); // 3
    
    // obj1.foo.call( obj2 ); // 3
    // obj2.foo.call( obj1 ); // 2
    
    // =====得出结论===>明确绑定 的优先权要高于 隐含绑定
    
    // function foo(something) {
    //     this.a = something;
    // }
    
    // var obj1 = {
    //     foo: foo
    // };
    
    // var obj2 = {};
    
    // obj1.foo( 2 );
    // console.log( obj1.a ); // 2
    
    // obj1.foo.call( obj2, 3 );
    // console.log( obj2.a ); // 3
    
    // var bar = new obj1.foo( 4 );
    // console.log( obj1.a ); // 2
    // console.log( bar.a ); // 4
    
    // =====得出结论===>new绑定 的优先级要高于 隐含绑定
    
    
    // 总结this
    // 现在,我们可以按照优先顺序来总结一下this的规则。
    
    // 1.new 绑定
    // 2.硬绑定
    // 3.明确绑定
    // 4.隐含绑定
    // 5.默认绑定
    
    // 以上,就是理解对于普通的函数调用来说的this绑定规则所需的全部。
    
    // 当然还有一些特殊的特例
    
    // 如果你传递null或undefined作为call,apply或bind的this绑定参数,那么这些值会被忽略掉,取而代之的是 默认绑定 规则将适用于这个调用。
    
    // function foo() {
    
    //     console.log( this.a );
    //     console.log( this );
    // }
    // var a = 2;
    // foo.call( null ); 
    
    
    // 扩展
    // 词法this   简单来说就是用一个变量保存this
    // 我们刚刚涵盖了一般函数遵守的4种规则。但是ES6引入了一种不适用于这些规则特殊的函数:箭头函数(arrow-function)。
    
    // 最后,复习一下
    // 为执行中的函数判定this绑定需要找到这个函数的直接调用点。找到之后,4种规则将会以 这个 优先顺序施用于调用点:
    
    /*
        1、被new调用?使用新构建的对象。
        2、被call或apply(或 bind)调用?使用指定的对象。
        3、被持有调用的环境对象调用?使用那个环境对象。
        4、默认:strict mode下是undefined,否则就是全局对象。
    */

    相关文章

      网友评论

          本文标题:js中的this

          本文链接:https://www.haomeiwen.com/subject/cdrzvttx.html