zoukankan      html  css  js  c++  java
  • 深入解读JavaScript面向对象编程实践

       Javascript是一门解释性脚本语言,同时它也是一门面向对象编程语言,但是它跟Java,c++等又不一样,因为它没有类(class),那么我们要如何把属性(

    property)和方法(method)封装成一个对象,从原型对象实例化出来一对象呢?

    一、对象类的创建

    在JavaScript中,我们通常可以使用构造函数来创建特定类型的对象。诸如Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中。 此外,我们也可以创建自定义的构造函数。

    1 function  Man(name, age, job) {
    2   this.name = name;
    3   this.age = age;
    4   this.job = job;
    5 }
    6 var man1 = new Person('Weiwei', 27, 'Student');
    7 var man2 = new Person('Lily', 25, 'Doctor');

       

     按照惯例,构造函数始终都应该以一个大写字母开头(和Java中定义的类一样),普通函数则小写字母开头。 要创建Person的新实例,必须使用new操作符。

    这样调用构造函数一般经过一下四个步骤:

    1. 创建一个新对象(实例)
    2. 将构造函数的作用域赋给新对象(也就是重设了this的指向,this就指向了这个新对象)
    3. 执行构造函数中的代码(为这个新对象添加属性)
    4. 返回新对象

      在上面的例子中,person1,person2 会默认都有一个constructor 属性,该属性指向它们的构造函数Man,即为

     console.log(person1.constructor == Person); //true

    console.log(person2.constructor == Person); //true 

    二、prototype 原型问题

    来看这段代码:

     1 function Man(name,age,job) {
     2 this.name = name ;
     3 this.age  = age;
     4 this.job = job;
     5 this.type = "person" ;
     6 this.action =function(){
     7 alert('walk');
     8 }
     9 }
    10 
    11 man1 = new Man("wei","20","student"); 12 console.log(man1.type); 13 //person

      这样子看起来好像没什么问题,但其实每次实例化,实例的 type 和 action 都是一样的, 这样就造成多次重复,占用了内存,实际上javascript规定,每个构造函数都有一个 prototype 属性,指向另一个对象,这个对象所有属性和方法,都会被实例化继承。

      也就是说,我们可以把那些不会变得属性和方法全部定义在 prototype 对象上。

    1 function Man(name,age,job){
    2     this.name = name;
    3     this.age = age;
    4        this.job = job;
    5   }
    6   Man.prototype.type = "person";
    7   Cat.prototype.action = function(){alert("walk")};

    然后生成实例;

    1  man1 =new Man("wei","20","student"); 

    2 alert(man1.type); //person

     

    上图展示了Man构造函数、Man的原型对象以及Man现有的实例之间的关系。

    • Person.prototype指向了原型对象
    • Person.prototype.constructor又指回了Person构造函数
    • Person的实例man1一个内部属性(通常为__proto__),man1.__proto__指向了原型对象

     三、 Prototype模式的验证方法

      为了配合 prototype 属性,javascript 定义了一些方法,帮助我们使用它。

     3.1   isPrototypeOf()

       这个方法用来判断,某个proptotype对象和某个实例之间的关系。

    1 alert(Man.prototype.isPrototypeOf(man1));
    2 // true;

    3.2  hasOwnProperty()

    每个实例对象都有一个 hasOwnProperty ()方法用于判断某一属性是来自本地属性,还是继承自prototype对象,若来自本地返回 true,否则返回 false;

    1 man1.hasOwnProperty("name");
    2 man1.hasOwnProperty("type");
    3 //true
    4 //false

    3.3 in 运算符

    同样 可以用 for in 来遍历对象

    1 for(var prop in man1){
    2 console.log("man1["+prop+"] = "+man1[prop]);
    3 }
    4 //man1[name] = ben
    5 // man1[age] = 20
    6 // man1[job] = student
    7 //man1[type] = person
    8 // man1[action] = function (){alert("walk")}

    同时 in 也可以用来检测属性是否在对象内,不管是本地对象,还是prototype 的属性

     1 console.log("eat" in man1);
     2 //false
     3 undefined
     4 console.log("type" in man1);
     5 
     6 //  true
     7 
     8 console.log("name" in man1);
     9 
    10 //true
  • 相关阅读:
    【3.5】类和实例属性的查找顺序--mro查找
    【3.4】类变量和实例变量
    【3.3】isinstance和type的区别
    【3.2】抽象基类(abc模块)
    【3.1】鸭子类型和多态
    学习笔记 | 浅谈虚拟函数(Virtual Function)
    学习笔记 | Udacity CarND Term 1: Computer Vision and Deep Learning
    命令行 | File Compression in Linux
    Python: if else in a list comprehension
    Topic | Hyperparameter Optimization for Neural Networks
  • 原文地址:https://www.cnblogs.com/benstos/p/5726982.html
Copyright © 2011-2022 走看看