JavaScript 面向对象编程【一】(实例对象与 new 命令)

  • A+

JavaScript 是一门集成了函数编程和面向对象编程的动态语言。它的对象是一个容器,封装了属性(property)和方法(method)。JavaScript的面向对象实现不是基于类,而是基于构造函数(constructor)和原型链(prototype)实现的。

一.概述

  1. JavaScript实现面向对象,是基于构造函数(constructor)和原型链(prototype)
  2. 构造函数和普通函数的区别? 构造函数内部使用this初始化属性,使用new创建相应对象。 具体见:构造函数介绍
  3. new关键字生成对象规则? ① 调用构造函数,如果带有return,若return返回对象,则生成此对象;若return返回不是对象,则生成this所代表的对象。 ② 调用普通函数,返回空对象具体见:new 命令生成对象规则

二.构造函数

1.介绍

  • 构造函数就是一个普通的函数,但是有自己的特征和用法。
  • 为了与普通函数区别,构造函数名字的第一个字母通常大写。并不是强制规定。
  • 构造函数的特点有两个,特征一:函数体内部使用了this关键字,代表了所要生成的对象实例。特征二:生成对象的时候,必须使用new命令。
  • 下面定义了一个构造函数
    var Vehicle = function () {
        this.price = 1000;
    };
    

三.new命令

1.使用new命令调用构造函数

  • 使用new命令调用构造函数,生成对象,构造函数也可以有参数。
    //生成对象时调用this,给对象添加属性
    var Vehicle = function () {
      this.price = 1000;
    };
    var v = new Vehicle();
    v.price // 1000
    
    //也可以添加参数
    var Vehicle = function (p) {
      this.price = p;
    };
    
    var v = new Vehicle(500);
    

2.构造函数与普通函数

  • 当构造函数被当做普通函数调用时候,this定义的属性将变为全局变量
  • 为了解决调用错误问题,一种是在构造函数内使用严格模式use strict,另一种是在构造函数内部使用instanceof关键字判断
    //一.严格模式
    function Fubar(foo, bar){
      'use strict';
      this._foo = foo;
      this._bar = bar;
    }
    
    Fubar()
    // TypeError: Cannot set property '_foo' of undefined
    //二.instanceof判断
    function Fubar(foo, bar) {
      if (!(this instanceof Fubar)) {
        return new Fubar(foo, bar);
      }
    
      this._foo = foo;
      this._bar = bar;
    }
    
    Fubar(1, 2)._foo // 1
    var f = new Fubar(1, 2)
    f._foo // 1
    

3.new 命令生成对象规则

  • 使用new调用构造函数:如果构造函数内部有return语句,而且return后面跟着一个对象,new命令会返回return语句指定的对象;否则,就会不管return语句,返回this对象。
  • 使用new调用普通函数(内部没有this关键字的函数),则会返回一个空对象。
    //一.构造函数返回非对象类型
    var Vehicle = function () {
      this.price = 1000;
      return 1000;
    };
    
    (new Vehicle()) === 1000
    // false
    
    //二.返回对象
    var Vehicle = function (){
      this.price = 1000;
      return { price: 2000 };
    };
    
    (new Vehicle()).price// 2000
    
    //三.调用普通函数返回空对象
    function getMessage() {
      return 'this is a message';
    }
    
    var msg = new getMessage();
    
    msg // {}
    typeof msg // "object"
    

4.new 命令生成对象流程

  1. 创建一个空对象,作为将要返回的对象实例。
  2. 将这个空对象的原型,指向构造函数的prototype属性。
  3. 将这个空对象赋值给函数内部的this关键字。
  4. 开始执行构造函数内部的代码。

5.new.target

  • 函数内部可以使用new.target属性。如果当前函数是new命令调用,new.target指向当前函数,否则为undefined
    function f() {
      console.log(new.target === f);
    }
    
    f() // false
    new f() // true
    
    //使用这个属性,可以判断函数调用的时候,是否使用new命令
    function f() {
      if (!new.target) {
        throw new Error('请使用 new 命令调用!');
      }
      // ...
    }
    
    f() // Uncaught Error: 请使用 new 命令调用!
    

四.Object.create() 创建实例对象

  • 根据现有的对象作为模板,生成新的实例对象,Object.create()
    var person1 = {
      name: 'Joey',
      age: 38,
      greeting: function() {
        console.log('Hi! I\'m ' + this.name + '.');
      }
    };
    
    var person2 = Object.create(person1);
    
    person2.name // Joey
    person2.greeting() // Hi! I'm Joey.
    
zhangfeng

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: