zoukankan      html  css  js  c++  java
  • 理解new构造函数和apply以及call

    今天在看设计模式的时候,遇到一些挺低级的东西,搞不懂,顾查阅资料整理记录一番。

    先了解一下new构造函数的过程:

    function func(){
       console.log('do');
    }
    
    var foo = new func();
    

    1、创建一个foo的空对象;

    2、将func内部的this指向foo函数;(继承func函数内部的属性和方法)

    3、foo._proto_ = func.prototye;(继承func的原型方法)

    4、执行一遍foo,为其初始化;

    5、返回一个foo对象;

    (2018/04/17)补充:

    1.创建一个foo空对象

    2.foo._proto_ = func.prototype;

    3.func.call(foo);

    4.return foo;

    二、call和apply的内部方法原理是一样的,只是使用方法不同。

    先来一段官方定义:call和apply用于更改函数的执行上下文环境。

    其实这样是很难理解的,到底什么意思呢?还是得上代码。

    1)替换函数对象

    function Cat() {
      this.animal = 'cat';
      console.log(this.animal);    
    }
    
    function Dog() {
      this.animal = 'dog';  
    }
    
    Cat.call(Dog); //cat
    

    内部执行可以分步骤进行:

    1、Cat函数内部的this指向Dog函数;

    2、执行Cat函数的函数上下文;

    3、this.animal即为Dog.animal,因此Dog.animal赋值为‘cat’;

    4、输出this.anmial即输出Dog.animal;

    2)直接调用函数内部的方法

    var func = {
      txt : 'text', 
      showTxt : function() {
          console.log(this.txt);
      }  
    }
    
    var foo = {
      txt : 'document'
    }
    
    func.showTxt.call(foo); // document
    

    步骤与例1差不多:

    1、func的this指向foo;

    2、执行func函数;

    3、执行foo.showTxt函数;由于showTxt此时的调用者为foo,因此,showTxt内部的this指向foo,所以foo.txt为document;

    此外,也有另一种请况:

    function func() {
      this.txt = 'text'; 
      this.showTxt = function() {
          console.log(this.txt);
      }  
    }
    
    function foo(){
      this.txt = 'document';
    }
    
    func.showTxt.call(foo); // TypeError
    

    这里会报错为TypeError,原因为并没有为foo对象进行初始化,只是执行了func的执行上下文。

    如果是这样:

    function func() {
      this.txt = 'text'; 
      this.showTxt = function() {
          console.log(this.txt);
      }  
    }
    
    function foo(){
      this.txt = 'document';
    }
    var m = new func();
    var n = new foo();
    m.showTxt.call(n); // document
    

    外部函数的内部函数的调用必须经过初始化。

    3)函数继承

    function func(){
      this.showName = function(){
         console.log(1111);
     }  
    }    
    
    function foo(){
       func.call(this);
    }
    
    var  son = new foo();
    son.showName();//1111
    

    理解了上面两个例子就容易理解了。

    (2018/04/17)补充:

    关于call和apply存在的意义:

    var func1 ={
        name : "jhon";
        say : function() {
             console.log(this.name)
        }  
    }    
    
    obj = {name:"lili"};
    
    func1.say.call(obj); // lili  (注意:call和apply方法只能作用于Object对象上,Function上是不存在的)
    

      

  • 相关阅读:
    BeanFactory 简介以及它 和FactoryBean的区别
    由kill 和 kill -9 引发的Linux signal 学习
    验证整数和小数的正则表达式
    重构!重构!重构!
    Java常用命令:jps、jstack、jmap、jstat(带有实例教程)
    子网掩码是4个255代表什么?
    常见的访问控制模型 Access Control Policy:RBAC,DAC,MAC,ABAC
    安装驱动
    大话数据治理-01什么是治理,治理什么数据
    提高 nginx 服务器 安全性,稳定性、性能 --经验总结-持续更新
  • 原文地址:https://www.cnblogs.com/Yoriluo/p/7489602.html
Copyright © 2011-2022 走看看