zoukankan      html  css  js  c++  java
  • 【Javascript】new一个函数和直接调用函数的区别以及new一个对象的过程

    一、new一个函数和直接调用函数的区别

    不使用new,也就是普通的函数调用而已,所以若是函数本身没有返回值,普通的函数调用没有什么意义
    如:
    var person=new Person();//person是一个对象

    var person = Person();//这只是一次普通的函数调用并赋值而已。

    function Person(name,age){  
      
    this.name=name;  
    this.age=age;  
    this.sayName=function(){  
    alert(this.name);  
          };  
    }  
      
    //var person=new Person("张三",20); //此处为 构造对象,构造对象的话,返回的新对象是由解析器自己生成的。  
    var person=Person("张三",20); //假设我在Person函数里面加了return "你好"; 这时的person就不会报undefined,而是一个字符串你好  
    person.sayName();//报错 person undefined 此处为普通函数调用,又没有给定返回值,出错。  
      
    //因为此时this指向window对象,  
    window.sayName();//此时不会报错  
      
    //接下来就问,为什么我赋值给person,可以用window来引用呢?  
    //因为如果不用new就相当于普通函数调用,而 Person()根本没有返回值,  
    //所以Person根本就没赋值给person,此时的person只是一个undefined,  
    //但是Person却执行了一次,成为了window的对象,this指向了window,所以window可以直接使用Person的方法, 

    如果构造函数返回值为常规意义上的数值类型(Number、String、Boolean)时,new函数将会返回一个该函数的实例对象,

    而如果构造函数返回一个引用类型(Object、Array、Function)时,则new函数与直接调用函数产生的结果相同,都返回这个引用。

    • 函数返回值为常规意义上的数值类型(Number、String、Boolean)
    function Test()  
      {  
          this.name = "test";  
          return "test";  
      }  
      var test1 = new Test();   //Object 对象,它有一个name 属性,并且返回一个字符串test  
      var test2 = Test();    // 函数Test()属于Function对象   这个test2,它单纯是一个字符串

    • 函数返回一个引用类型(Object、Array、Function)(工厂模式):
    function Person(name,age) 
        { 
            var o = new Object(); 
            o.name = name; 
            o.age = age; 
            o.getName = function() 
            { 
                alert(this.name); 
            } 
            return o; 
        } 
        var obj1 = new Person("liwen",25); 
        var obj2 = Person("liwen1",25); 
        obj1.getName();  //liwen       new一个函数的实例对象  
        obj2.getName();  //liwen1      直接调用  

    二、new一个对象的过程

    首先我们看下new Person输出什么?

    var Person = function(name, age) {
            this.name = name;
            this.age = age;
        };
        Person.prototype.show = function() {
            console.log(this.name, this.age);
        };
        var p = new Person("bella", 10);
        console.log(p);

    对象p里有属性name, age 和 __proto__;

    __proto__里面有原型方法show,constructor, __proto__;

    然后我们再输出构造器Person.prototype:

    对比一下,发现p的__proto__的值就是构造函数Person的prototype的属性值。

    因此new操作符创建对象可以分为以下四个步骤:

      • 创建一个空对象
      • 将所创建对象的__proto__属性值设为构造函数的prototype的属性值
      • 执行构造函数中的代码,构造函数中的this指向该对象
      • 返回对象

    因此上面的过程就可以等同于下面的过程:

    var Person = function(name, age) {
            this.name = name;
            this.age = age;
        };
        Person.prototype.show = function() {
            console.log(this.name, this.age);
        };
        var p = {};
        p.__proto__ = Person.prototype;
        Person.call(p, "balle", 10);
        // var p = new Person("bella", 10);
        console.log(p);
  • 相关阅读:
    第三章 AOP
    第二章 IoC
    第一章 Spring 概述
    框架整合
    后台管理工程搭建
    技术架构
    淘淘商城简介
    电商行业背景
    前言
    FutureTask的使用
  • 原文地址:https://www.cnblogs.com/vickylinj/p/13755906.html
Copyright © 2011-2022 走看看