javascript——原型、原型对象、原型链

67 篇文章 0 订阅
18 篇文章 1 订阅
本文深入探讨JavaScript中的原型和原型链概念。通过实例解释了构造函数的prototype属性、实例对象的__proto__属性以及它们之间的关系。讨论了如何在原型上添加属性和方法,以及如何通过原型链查找对象属性。同时提到了垃圾回收机制,说明了如何释放不再使用的对象内存。
摘要由CSDN通过智能技术生成

原型

​ 将函数定义在全局作用域,污染了全局作用域的命名空间,而且定义在全局作用域中也很不安全

原型(prototype):创建每一个的函数,解析器都会向函数中添加一个属性(prototype),这个属性对应着一个对象,这个对象就是所谓的原型对象

如果函数作为普通函数调用prototype没有任何作用;当函数作为构造函数调用时,它所创建的对象中都会有一个隐含的属性(_proto_),指向该构造函数的原型对象,我们可以通过__proto__来访问该属性。原型(prototype)指向一个对象(原型对象),所以原型对象也含有__proto__属性

构造函数的原型prototype和该实例对象的__proto__属性指向的是同一个对象(对象的__proto__属性指向构造它的构造函数的原型对象)

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将一类对象中共有的属性和方法,统一设置到构造函数的原型对象中,这样就不会影响到全局作用域

函数中的是prototype属性,指向原型对象;对象中的是__proto__属性,也是指向原型对象(对象的__proto__属性指向它的构造函数的原型对象)

当我们访问对象的一个属性或方法时,它会先在对象自身寻找,如果有则直接使用;如果没有,则会去原型对象(prototype)中寻找,如果找到则直接使用;如果再没有就去原型对象的原型(__proto__)中寻找,如果原型中有,则使用;如果再没有则去原型的原型中寻找,直到找到Object对象的原型。Object对象的原型(__proto__)没有原型,如果在Object中仍然没有找到,则返回null

 <script>
        // 构造函数
        function Person() {

        }
        // 向Person的原型中添加一个属性name
        Person.prototype.name = "张三";
        // 向Person的原型中添加一个方法
        Person.prototype.sayHi = function() {
            // 构造函数中的this指向它创建的实例对象
            console.log(this.name);
        };
        // 创建Person的实例对象
        var p1 = new Person();
        var p2 = new Person();
        p2.name = "李四";
        // prototype原型
        console.log(Person.prototype);
        console.log(p1.__proto__);
        console.log(Person.prototype == p1.__proto__); //true
        console.log(p1.name); //p1自身没有name属性,则去原型找,name属性值是原型对象中的name属性值,值为张三
        console.log(p2.name); //p2自身具有name属性,所以name属性是自身的属性,值为李四
        p1.sayHi(); //p1里面没有方法,去原型里面找
// 构造函数的prototype属性的指向和它的实例对象的__proto__属性的指向的相同的,指向同一个对象
        console.log(Person.prototype == p1.__proto__); //true
        // 构造函数的prototype属性指向它的原型对象,原型对象也是对象,所以也拥有__proto__属性
        console.log(Person.prototype.__proto__ == p1.__proto__.__proto__); //true
    </script>

使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true

使用hasOwnProperty()方法检查对象中是否含有某个属性,只有对象自身存在该属性才会返回true

<script>
        // 构造函数
        function Person() {

        }
        // 向Person的原型中添加一个属性name
        Person.prototype.name = "我是原型中的张三";
        // 创建Person的实例对象
        var p1 = new Person();
        p1.age = 22;
        // 检查p1中是否含有name属性
        console.log("name" in Person); //true
        console.log("name" in p1); //true
        // 可以使用对象hasOwnProperty()方法来检查对象中是否含有该属性,只有对象自身中含有这个属性才会返回true
        console.log(p1.hasOwnProperty("name")); //p1自身不含有这个属性,所以返回false
        console.log(p1.hasOwnProperty("age")); //p1自身含有age属性,所以返回true

        console.log(p1.hasOwnProperty('hasOwnProperty')); //false
        console.log(p1.__proto__.hasOwnProperty('hasOwnProperty')); //false
        // 说明hasOwnProperty方法是存在于对象的原型对象(p1.__proto__)的原型(__proto__)中
        console.log(p1.__proto__.__proto__.hasOwnProperty('hasOwnProperty')); //true
        // 对象的对象原型(__proto__属性)指向它的构造函数的原型(prototype属性),两个属性所指的对象是同一个对象
        // 对象的对象原型__proto__指向原型对象(构造函数的原型prototype的指向),原型对象的原型__proto__指向它的构造函数的原型(构造函数的的原型对象的原型指向Object构造函数的原型对象)
        // Object构造函数的原型对象的原型__proto__指向的原型对象不存在(Object是最高级了)
        // 原型链
        console.log(p1.__proto__.__proto__.__proto__); //null
    </script>

toString方法产生的问题

<script>
        // 创建构造函数
        function Person(name, age, gender) {
            this.name = name;
            this.age = age;
            this.gender = gender;
        }
        // 给构造函数的原型添加toString方法,由Person创建出来的对象,都会有这个toString方法
        Person.prototype.toString = function() {
            return "Person[name=" + this.name + ",age=" + this.age + ",gender=" + this.gender + "]";
        };
        // 创建一个Person实例
        var p = new Person('zs', 22, '男');
        var s = new Person('ls', 28, '男');

        // 当我们直接在页面中打印一个对象时,实际上是输出的对象的toString()方法的返回值
        // 如果不希望在输出对象时不输出[object Object],可以给对象添加一个toString()方法
        // 单独给对象加toString()方法,这样只对该对象有效
        /* p.toString = function() {
            return "Person[name=" + this.name + ",age=" + this.age + ",gender=" + this.gender + "]";
        }; */

        console.log(p.toString());
        console.log(s.toString());

        // console.log(p);
        // var res = p.toString();
        // console.log('res:' + res); //res:[object Object]
        // 这个toString方法是存放在Object的原型中
        console.log(p.__proto__.__proto__.hasOwnProperty("toString")); //true
    </script>

垃圾回收(垃圾收集)

当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,这种对象就过多的占用大量的内存空间,导致程序运行变慢。

在js中拥有自动的垃圾回收的机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作

我们需要手动将不再需要使用的对象设置为null即可

<script>
        var obj = new Object();
        // 一顿操作之后
        obj = null;
        // 我们只需要将obj设为null,剩下的就交给js的垃圾回收机制处理
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值