zoukankan      html  css  js  c++  java
  • js的new操作符深度解析

    引言

    • 我们都知道new操作符在js中一般是用来创建一个构造函数的实例,它在创建实例具体做了什么,MDN文档是这么说的: 我一开始看到,完全没有任何的头绪和理解,到底什么意思,后面通过上网查阅了大量的资料,对new操作符有了初步的认识。

    1、创建一个空的简单JavaScript对象(即{});
    2、链接该对象(即设置该对象的构造函数)到另一个对象 ;
    3、将步骤1新创建的对象作为this的上下文 ;
    4、如果该函数没有返回对象,则返回this。

    普通函数和构造函数的区别

    • 在js中 普通函数和构造函数并无本质的区别,都是函数,构造函数约定首字母大写(主要目的区分普通函数和构造函数)。并且通过new操作符调用并创建构造函数的实例。

    new操作符做了什么

    
     var _this = null
     function Fun(){
         this.name = '车神-黄杰'
         this.gender = '男'
         this.age = 23
    	
         _this = this		
         console.log('this--->', this)
     }
    
     var foo = new Fun()		
     console.log('foo--->', foo)
     console.log('foo === _this--->', foo === _this)
     console.log('name--->', foo.name)
    
    

    输出结果

    创建空对象(第一步)

    
     var fun = new Object()
    

    链接该对象(第二步)

    • 其实就是设置了第一步创建的空对象fun__proto__属性 和 构造函数Funprototype属性指向同一块内存地址。
    
     var fun = new Object()// 1
     fun .__proto__ = Fun.prototype// 2
    

    新创建的对象作为this的上下文(第三步)

    • 这里和第二步类似,即第一步创建的空对象funthis指向同一块内存地址(这是我个人理解)
    
     var fun = new Object()// 1
     fun .__proto__ = Fun.prototype// 2
     this = fun// 3
    

    返回值(第四步)

    • 我们知道函数的调用即为函数名,后面紧跟一个括号,创建构造函数的实例是 new Fun(),自然会调用构造函数,那构造函数里面的代码必然会执行。当构造函数没有返回具体对象(注意这里是对象),默认是返回this。执行var foo = new Fun()这一句代码即为foo接收了返回值this,结果就是foo也指向了this所指向的内存地址。说白了空对象funthis、实例foo指向了同一块内存地址。当你往this添加了name、gender、age属性,自然实例foo也能访问到。

    隐式参数

    • 为什么函数调用的时候没有传递this和arguments,却可以使用它们呢,原因就是在调用函数的时候会默认传递两个隐式参数this和arguments,其中的this即为第三步的thisarguments是一个伪数组对象,包含着传入函数中的所有参数。

    构造函数有具体的返回对象

    • 当构造函数有返回新的对象(注意这里是对象),执行var foo = new Fun()这一句代码,foo接收的值为构造函数返回的具体的对象。
    
     var _this = null
     function Fun(){
         this.name = '车神-黄杰'
         this.gender = '男'
         this.age = 23
    	
         _this = this		
         console.log('this--->', this)
        
        //返回新的对象
         return {name: '我是新的name'}
     }
    
     var foo = new Fun()		
     console.log('foo--->', foo)
     console.log('foo === _this--->', foo === _this)
     console.log('name--->', foo.name)
    
    

    输出结果

    模拟new操作符

    • 这里用到了函数对象的两个主要的方法apply、call,总的来说就是可以调用函数并且绑定具体this
     function cloneNew(){
    				
         //先获取传递进来的构造函数对象 
         //默认为第一个参数 由于arguments不是数组
         //不能直接使用数组的shift方法(自己了解 shift 的方法使用)
         //可以通过函数的shift方法返回第一个参数
        //并去除arguments的第一个参数
         var constructor = [].shift.call(arguments)				
    				
         //第一步:创建一个空对象
         var obj = new Object()
    				
         //第二步:链接该对象
         obj.__proto__ = constructor.prototype
    				
         //第三步:新创建的对象作为this的上下文 
         //这里借助函数对象的 apply 方法,对应还有一个 call 方法
         var newObj = constructor.apply(obj,arguments)
    				
         //第四步:判断构造函数有没有返回具体的对象
         return newObj instanceof Object ? newObj : obj				
     }
    			
     //返回this			
     function Fun(name){
         this.name = name
     }
    
     //返回具体对象			
     function Foo(name){
         this.name = name
         //返回具体得到对象
         return {name: '新的黄杰'}
     }
    			
     var fun = cloneNew(Fun, '黄杰')
     var foo = cloneNew(Foo, '黄杰')
    			
     console.log('this的name--->'+ fun.name)// 输出 黄杰
     console.log('构造函数返回具体对象的name--->'+ foo.name)//输出 新的黄杰
    
    

    输出结果

    注意

    • 这里完全讨论的是new操作符,没有具体讨论this的指向问题,本人也在不断努力学习中,如有错误,恳请多多指教。
  • 相关阅读:
    lr 增强窗格中,如何生成调试信息?
    lr 自带的例子,如何进行关联,通过代码的函数进行实现
    lr11 录制脚本时候,无法自动启动ie,查了网上很多方法都未解决?
    loadrunner11 录制脚步不成功,在录制概要出现“No Events were detected”,浮动窗口总是显示“0 Events”,解决办法
    loadrunner11 安装及破解教程来自百度文库
    安装loadrunner11 ,出现如下错误如何解决?
    回收站数据删除了,如何进行恢复?
    网管工作方面——————打印机删除了然后开机重启他依然存在,如何解决
    Windows 不能在 本地计算机 启动 SQL Server 服务 错误代码126
    Sorry, the page you are looking for is currently unavailable. Please try again later. Nginx
  • 原文地址:https://www.cnblogs.com/HJ412/p/11235831.html
Copyright © 2011-2022 走看看