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
  • 相关阅读:
    ubuntu安装jdk的两种方法
    LeetCode 606. Construct String from Binary Tree (建立一个二叉树的string)
    LeetCode 617. Merge Two Binary Tree (合并两个二叉树)
    LeetCode 476. Number Complement (数的补数)
    LeetCode 575. Distribute Candies (发糖果)
    LeetCode 461. Hamming Distance (汉明距离)
    LeetCode 405. Convert a Number to Hexadecimal (把一个数转化为16进制)
    LeetCode 594. Longest Harmonious Subsequence (最长的协调子序列)
    LeetCode 371. Sum of Two Integers (两数之和)
    LeetCode 342. Power of Four (4的次方)
  • 原文地址:https://www.cnblogs.com/benstos/p/5726982.html
Copyright © 2011-2022 走看看