• javascript高级知识分析——实例化


    代码信息来自于http://ejohn.org/apps/learn/。

    new做了什么?

    function Ninja(){ 
      this.name = "Ninja"; 
    } 
     
    var ninjaA = Ninja(); 
    console.log( ninjaA, "undefined,ninja并不是实例化" ); 
     
    var ninjaB = new Ninja(); 
    console.log( ninjaB.name == "Ninja", "true,在实例化里存在name属性" )

    对一个函数进行new操作,这就是实例化。

    上述代码的流程为,创造一个临时对象,继承Ninja.prototype对象,执行函数Ninja,一开始将上下文this设置为临时对象。没有return语句,返回这个临时对象。

    我们的上下文this指向实例化对象

    function Ninja(){ 
      this.swung = false; 
       
      // Should return true 
      this.swingSword = function(){ 
        this.swung = !this.swung; 
        return this.swung; 
      }; 
    } 
     
    var ninja = new Ninja(); 
    console.log( ninja.swingSword(), "调用实例对象方法" ); 
    console.log( ninja.swung, "引用实例对象属性" ); 
     
    var ninjaB = new Ninja(); 
    console.log( !ninjaB.swung, "确定this引用的属性是实例化对象的属性,实例化对象彼此不影响." );

    习题:增加一个方法,可以给ninja一个name属性

    function Ninja(name){ 
      //补足
    } 
     
    var ninja = new Ninja("John"); 
    console.log( ninja.name == "John", "在初始化时name属性就被设置" ); 
     
    ninja.changeName("Bob"); 
    console.log( ninja.name == "Bob", "name值成功修改" );

    向实例化对象增加一个新的属性和方法

    function Ninja(name){ 
      this.changeName = function(name){
         this.name = name;
      }
      this.changeName(name)
    } 
     
    var ninja = new Ninja("John"); 
    console.log( ninja.name == "John", "在初始化时name属性就被设置" ); 
     
    ninja.changeName("Bob"); 
    console.log( ninja.name == "Bob", "name值成功修改" );

    当没有使用new时会发生什么?

    function User(first, last){ 
      this.name = first + " " + last; 
    } 
     
    var user = User("John", "Resig"); 
    console.log( typeof user == "undefined", "因为没有new,所以User作一般函数调用,没有返回值" );
    function User(first, last){ 
      this.name = first + " " + last; 
    } 
     
    window.name = "Resig"; 
    var user = User("John", name); 
     
    console.log( name == "John Resig", "全局属性被覆盖" );

    当没有new时,它其实就是一般的函数调用,遵循函数调用的本质。

    确保在错误的情况下仍然使用对象实例化

    function User(first, last){ 
      if ( !(this instanceof User) ) 
        return new User(first, last); 
      this.name = first + " " + last; 
    } 
     
    var name = "Resig"; 
    var user = User("John", name); 
     
    console.log( user, "即使没有使用new,仍然可以正确实例化" ); 
    console.log( name == "Resig", "实例化属性正常" );

    通过判断this不是构造函数User的实例化对象,重新实例化,这是一个可以不使用new进行实例化的技巧。

    习题:有没有更加基因化的方法做同样的事情?

    function User(first, last){ 
      if ( !(this instanceof ___) ) 
        return new User(first, last); 
      this.name = first + " " + last; 
    } 
     
    var name = "Resig"; 
    var user = User("John", name); 
     
    console.log( user, "即使没有使用new,仍然可以正确实例化" ); 
    console.log( name == "Resig", "实例化属性正常" );

    用arguments.callee实现

    function User(first, last){ 
      if ( !(this instanceof ___) ) 
        return new User(first, last); 
      this.name = first + " " + last; 
    } 
     
    var name = "Resig"; 
    var user = User("John", name); 
     
    console.log( user, "即使没有使用new,仍然可以正确实例化" ); 
    console.log( name == "Resig", "实例化属性正常" );

    arguments.callee引用的是函数本身。

  • 相关阅读:
    C#进阶系列——WebApi 路由机制剖析:你准备好了吗?
    Socket长连接和短连接的区别
    C#socket通信时,怎样判断socket双方是否断开连接
    Redis常见面试题
    [C# 线程处理系列]专题三:线程池中的I/O线程
    结对编程第一次作业
    软件工程第三次作业
    软件工程第二次作业
    人生中的第一篇博客
    CPU 分类
  • 原文地址:https://www.cnblogs.com/winderby/p/4064448.html
Copyright © 2020-2023  润新知