美文网首页
this 原型和原型链

this 原型和原型链

作者: 蜕变最美的你 | 来源:发表于2017-08-09 09:54 被阅读0次
    输出什么?为什么?
    var john = { 
      firstName: "John" 
    }
    function func() { 
      alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()   
    

    输出为 "John:hi!" ,因为john是一个由字面量构建的对象,并进行了初始化,添加属性为firstName属性值为"John" ;通过添加属性给john对象添加了一个sayHi属性并赋值为一个函数名为func的函数,即作为了john的方法;当我执行john.sayHi() 时调用func()方法,func()方法中的this.firstName 的指向是john对象,即john对象中的firstName值"John" 拼接后面的字符串": hi!"得到最后结果;

    call,apply,bind的用法是什么?

    call,apply,bind 这三种方法主要用在改变this指向问题(bind是ES5新增方法);
    call和apply的第一个参数相同,只是在第二参数之后有区别,call传递的第二个参数是一一列举用逗号分隔,apply传递的第二个参数是数组,call和apply都是对函数的直接调用;

    bind与上面两种方法类似,bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以。

    //call,apply,bind 写法:
    say.call(xh,"a","b");
    say.apply(xh,["a","b"]);
    say.bind(xh)("a","b");
    
    输出什么?为什么?
    var john = {
            firstName: "John"
        };
    
        function func() {
            alert( this.firstName )
        }
        func.call(john)
    

    输出结果为 "john",当执行fun()函数时由于使用了call方法所以 func()的this指针由window变成了john这个对象,等于给john对象增加了一个func()方法,func()方法中的this.firstName 就是john对象中的firstName属性的值 "John";

    以下代码有什么问题,如何修改?
    var module= {
      bind: function(){
        $btn.on('click', function(){
          console.log(this)   //this指什么?
          this.showMsg();
        })
      },
      
      showMsg: function(){
        console.log('哈哈');
      }
    }
    

    首先没有调用module的bind()方法, this.showMsg(); 这里的this指向 btn 找不到showMsg(),要修改这里的this指向为 module即可,btn找不到此变量;见下列代码:

    var module= {
            bind: function(){
                var $btn = document.getElementById('btn');
                document.addEventListener('click', function(){
                    console.log(this);  //this指什么?  $btn
                    module.showMsg.call(module);
                },false)
            },
    
            showMsg: function(){
                console.log('哈哈');
            }
        };
      module.bind();
    
    有如下代码,解释Person、 prototype、proto、p、constructor之间的关联?
    function Person(name){
          this.name = name;
      }
      Person.prototype.sayName = function(){
          console.log('My name is :' + this.name);
      };
      var p = new Person("若愚");
      p.sayName();
    

    使用new操作符实例化了一个p对象,并建立构造函数Person传入参数为"若愚",被实例化对象有一个属性为proto,构造函数Person接收构造函数的参数为"若愚",构造函数Person有一个属性prototype,p.proto == Person.prototype ;所以 this.name = name;可以理解为实例化p对象的name属性值为"若愚";Person.prototype有一个constructor属性指向为构造函数的本身,把构造函数的属性给实例的p对象,Person.prototype.sayName()是给构造函数Person.prototype属性增加了一个方法,所以方法中的this指向的是实例化的p对象;

    下面两种写法有什么区别?
    function People(name, sex){
        this.name = name;
        this.sex = sex;
        this.printName = function(){
            console.log(this.name);
        }
    }
    var p1 = new People('哈哈', 2)
    
    //方法2
    function Person(name, sex){
        this.name = name;
        this.sex = sex;
    }
    
    Person.prototype.printName = function(){
        console.log(this.name);
    }
    var p1 = new Person('你好', 27);
    

    调用方法基本相同,只是在读代码时,调用 People()时会把函数的内容从上到下读一遍即使你实例的对象不需要里面的方法,非常消耗内存影响性能,第二种是一种更优化的写法,实例化的对象只有在调用这个方法时才会读取函数的内容;推荐第二种写法;

    相关文章

      网友评论

          本文标题:this 原型和原型链

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