• JS基础如何理解对象


    这几天跟几个同事聊天发现他们对javascript什么时候该用new都不是很了解。

    1、javascript的function什么时候该new什么时候不该new?
    我觉得主要的问题还是集中在javascript的弱类型上面。


    new在干什么

    首先我们知道new是干什么,以我们java或.net的语言经验显然在创造对象。是的,不管是java还是.net。他是在创建一个对象。

    new后面是什么

    那么我们考虑一下new的后面是什么,(java和.net)一般是被一个class修饰的类名称。那么我们考虑一下,我们实例一个对象是干什么或者说设计者的目的是什么,那么一般情况下对象都会包含这些成员,属性与行为或者其中之一(我们在javaEE中DAO只有行为,POJO只有属性),有没有看到过既没有属性也没有行为的对象(当然类可以这么设计,但是没有意义)。

    javascript的new干了什么
    那么javascript的new干了什么?new其实开辟了内存空间创建了一个object这个object就是this,然后这个this的prototype指向了函数本身的prototype。
    也就是说去new一个function的时候,开辟了一个this,这个this就是对象本身,再想想你去实例一个对象。你要拿到对象的成员,属性或方法或其中之一。this本身有几种方式能声明成员,一种在function函数体内部用this.的方式声明,例如:this.a = '123',其实就是给他的a属性赋了一个‘123’字符串,当然也可以赋值行为。还有种方式就是通过原型继承,通过function函数的.prototype的方式。
    好了,因为javascript是弱类型,他没有class修饰,没有是否有返回值修饰,只有一个function修饰。所以function是否是构造函数很难通过函数头知道。所以是否需要去new就需要你去揣摩function的目的,他到底是不是构造函数。

    实例代码说明
    既然他是弱类型,他们可以根据内部的条件选择到底是做构造函数用,还是做普通函数用。再加上我们很多程序员都是其他语言出身,很少有人系统的学习了javascript,所以就很混淆。
    下面我们来看混淆的例子吧。

    Js代码 

    • function Hello() {  
    •     this.a = '123';  
    •     this.b = function () {  
    •         alert('b');  
    •     }  
    •   
    •     return this;  
    • }  
    •   
    • Hello.prototype.c = function() {  
    •     alert('c');  
    • }  
    • var aHello = new Hello();  
    • var bHello = Hello();  
    • alert(aHello.a)  
    • alert(bHello.a)  
    • aHello.b();  
    • bHello.b();  
    • aHello.c();  
    • bHello.c();  

    你会发现bHello.c()是执行不了的。在看看上面的函数,他为什么既能new又能不new。
    new其实开辟了内存空间创建了一个object这个object就是this,然后这个this的prototype指向了函数本身的prototype。
    不new就是执行了这个函数,最后return this就是返回了这个执行函数的宿主,其实就是window本身。
    所以c函数是绑定在Hello的prototype上的,所以window上根本没有。

    但是就出现了一个问题,就是如果在不执行c方法或者c本身不是通过原型继承的方式的话(就是不通过Hello的prototype方式,通过直接给this赋值的方式),其实创建的this的内容和window增加的内容是一样的,程序员会本能的以为new和不new是一样的。这样就掉坑里去了。

    总结:javascript弱类型语言,一个函数即使是普通的执行函数,你new或不new都会出现编译器异常。
    new与不new我们要做好以下几点。
    1、首先大家要了解new本身干了什么,然后看函数创建者的意图,看函数结构。
    2、一个好的程序员在提供某个javascript工具类或公用方法时,应该注释告诉你的调用者怎么去使用你提供的公用内容,或者提供工厂方法。

  • 相关阅读:
    nginx 安装部署
    cordova 安装使用
    git 设置和取消代理
    SQL语句 合并列值 将一列的多个值合并成一行
    idea 注册码 地址:
    mac 安装redis
    redisTemplate 方法
    js 点击 隐藏弹出层
    windows 安装redis
    docker 安装redis
  • 原文地址:https://www.cnblogs.com/newzhq/p/4543650.html
Copyright © 2020-2023  润新知