• class(类)和构造函数(原型对象)


    最近在看R框架,不得不去看一下构造函数和class的关系了,还有面向对象和原型对象,其实很多人都会很困惑这些概念

    一. 构造函数和原型 

      1.function 声明(创造)了一个函数 Person,叫构造函数

      2.原型对象:在声明了一个函数之后,浏览器会自动按照一定的规则创建一个对象,这个对象就叫做原型对象。这个原型对象其实是储存在了内存当中。

      3.在声明了一个函数后,这个构造函数(声明了的函数)中会有一个属性prototype,这个属性指向的就是这个构造函数(声明了的函数)对应的原型对象;原型对象中有一个属性constructor,这个属性指向的是这个构造函数(声明了的函数)。

      所以说:Person(构造函数)的 prototype 指向原型对象,原型对象的 constructor 属性,又指向该构造函数本身

    1 function Person(name, age) {
    2       this.name = name;
    3       this.age = age;
    4     }
    5     console.log(Person);                               // 构造函数本身
    6     console.log(Person.prototype.constructor);         // 指向 构造函数本身
    7     Person("范顺", 18);

     二. 构造函数使用new来创建对象 

    1 function students() {
    2   
    3     }
    4   
    5 var stu = new students();

      1.  stu 是 new students()(构造函数) 创建出来的对象,这个stu对象中是没有prototype属性的,prototype属性只有在构造函数students中有

      2. 但stu(创建出来的对象)有一个__proto__属性,stu调用这个属性可以直接访问到构造函数students的原型对象(也就是说,stu的__proto__属性指向的是构造函数的原型对象)

      所以:stu.__proto__ = students.prototype 都指向原型对象

     

       3. 我们给原型对象添加属性和方法,那么 new 出来的这个对象就可以访问到该原型对象的属性和方法

     1 function students() {
     2       /* 我就是构造函数 */
     3     }
     4     students.prototype.name="shun"
     5     var stu = new students();
     6     console.log(stu.__proto__.name);  // 访问到原型对象添加的属性
     7     console.log(stu.name);  // 这样也是能访问到原型对象添加的属性,因为stu本身没有这个name属性,所以说会向stu对象的__proto__ 属性指向的原型对象中找,找到就返回,找不到就往上找,就是原型链
     8     
     9     stu.name = "fan"      // 给stu对象添加属性
    10     console.log(stu.name);  // 访问stu对象的属性

      4. 因为 new 出来的 stu 是一个对象,我们也可以给它直接设置属性,如果找到直接返回值,如果stu对象本身没有这个属性,那么就会向上找stu对象的__proto__属性指向的原型对象中查找,如果查找到则返回。(如果原型中也没有找到,则继续向上找原型的原型 这就是所说的原型链
      5. 如果通过stu对象添加了一个属性name,则stu对象来说就屏蔽了原型中的属性name。 换句话说:在stu中就没有办法访问到原型的属性name了。
    通过stu对象只能读取原型中的属性name的值,而不能修改原型中的属性name的值。 stu.name = “李四”; 并不是修改了原型中的值,而是在stu对象中给添加了一个属性name

    <script type="text/javascript">
            function students () {       
            }
            // 可以使用students.prototype 直接访问到原型对象
            //给students函数的原型对象中添加一个属性 name并且值是 "张三"
            students.prototype.name = "张三";
            students.prototype.age = 20;
      
            var stu = new students();
            /*
                访问stu对象的属性name,虽然在stu对象中我们并没有明确的添加属性name,但是
                stu的__proto__属性指向的原型中有name属性,所以这个地方可以访问到属性name
                就值。
                注意:这个时候不能通过stu对象删除name属性,因为只能删除在stu中删除的对象。
            */
            alert(stu.name);  // 张三
      
            var stu1 = new students();
            alert(stu1.name);  // 张三  都是从原型中找到的,所以一样。
      
            alert(stu.name === stu1.name);  // true
      
            // 由于不能修改原型中的值,则这种方法就直接在stu中添加了一个新的属性name,然后在stu中无法再访问到
            //原型中的属性。
            stu.name = "李四";
            alert(stu.name); //李四
            // 由于stu1中没有name属性,则对stu1来说仍然是访问的原型中的属性。   
            alert(stu1.name);  // 张三 
        </script>

    三. 与原型有关的几个方法
    **1. prototype属性**

    prototype 存在于构造函数中 (其实任意函数中都有,只是不是构造函数的时候prototype我们不关注而已) ,他指向了这个构造函数的原型对象。

    **2.constructor属性**

    constructor属性存在于原型对象中,他指向了构造函数

    如下面代码:

    <script type="text/javascript">
    function students () {
    }
    alert(students.prototype.constructor === students); // true
    </script> 

    我们根据需要,可以students.prototype 属性指定新的对象,来作为students的原型对象。但是这个时候有个问题,新的对象的constructor属性则不再指向students构造函数了。

    **3.__proto__ 属性(注意:左右各是2个下划线)**

    用构造方法创建一个新的对象之后,这个对象中默认会有一个属性__proto__, 这个属性就指向了构造方法的原型对象。

    四. class(类)

  • 相关阅读:
    Visual Studio调试提示未能找到路径 bin oslyncsc.exe
    泛型
    Java中System.setProperty()
    jQuery的基础·知识
    移动端事件与touch.js库(js)
    js中,求1~100之间的质数
    匿名函数,闭包与ajax(js)
    正则(js)
    面向对象的概念,创建,实例,call与apply,继承(js)
    事件基础,事件绑定,DOM事件流与事件的默认行为,键盘事件,滚轮事件,事件委托(js)
  • 原文地址:https://www.cnblogs.com/shun1015/p/13443141.html
Copyright © 2020-2023  润新知