JS 构造函数

一、构造函数(用ES6之前的方法)

        function Star(uname, age) { // 构造函数
            this.uname = uname;
            this.age = age;
            this.sing = function () {
                console.log('123');
            }
        }
        var ldh = new Star('Ldh', 18); // 使用构造函数创建对象
        ldh.sing();

1.实例成员

(1)实例成员是构造函数内部通过this添加的成员,如uname, age, sing都是实例成员。

        console.log(ldh.uname); // 访问实例成员

(2)实例成员只能通过实例化的对象来访问。

2.静态成员

(1)静态成员是在构造函数本身上添加的成员。

        Star.gender='男'; // 创建静态成员

(2)静态成员只能通过构造函数来访问

        console.log(Star.gender); // 访问静态成员

3.构造函数的缺点

浪费内存空间。

在创建对象时,简单数据类型如属性可以存放在一起,但是复杂数据类型如函数却新开辟了一个空间,每一个对象的复杂数据类型都新开辟了一个属于自己的新空间,但是很多对象的函数功能都是一样的,这样就造成了内存空间浪费的问题。

4.解决方法:构造函数原型:prototype

原型就是为了共享函数,简化内存。

每个构造函数都有一个prototype,把不变的方法都定义在phrototype对象上,可以让所有的对象实例共享这些方法。

        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        Star.prototype.sing = function () {
            console.log('123');
        }
        var ldh = new Star('Ldh', 18); // 使用构造函数创建对象
        ldh.sing(); // 使用原型

5.__proto__

在刚刚新建对象之后,我们可以输出ldh查看是否存在ptototype,

Star {uname: 'Ldh', age: 18}
age: 18
uname: "Ldh"
[[Prototype]]: Object

此时,输出的结果时这样的,可以看到里面也有prototype的相关内容。

我们如果想要访问这个原型对象

        console.log(ldh.__proto__); //访问实例对象的原型对象
        // 结果:{sing: ƒ, constructor: ƒ}

相当于Star.prototype

        console.log(ldh.__proto__ === Star.prototype);//结果:true

6.函数的查找顺序:

在执行ldh.sing(); 时,先查找ldh实例对象本身是否有sing的方法,如果有的话就执行这个对象上的sing函数,如果没有的话就去查找__proto__,去构造函数原型对象上去找sing()函数。如果原型上面也没有就报错。ldh.sing is not a function。

7.称呼

prototype:原型对象

__proto__:对象的原型

8.构造函数 constructor

prototype和__proto__中都有一个constructor函数,用来指向构造函数,是谁创建的原型就指向谁。

        console.log(ldh.__proto__.constructor); // 访问构造原型的构造函数
       
         //返回的结果就是构造函数本身
        ƒ Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }

9.constructor被覆盖的原因

我们在实际工程中,原型对象包含的函数不止一个,会出现以下情况

        Star.prototype = {
            sing: function () {
                console.log(123);
            },
            dance: function () {
                console.log(456);
            }
        }

用这种方法用更加条理清晰,但是这种方法是利用对象把原来的prototype给覆盖掉,constructor也被覆盖掉

        Star.prototype = {
            constructor: Star; // 用constructor指回原来的构造函数
            sing: function () {
                console.log(123);
            },
            dance: function () {
                console.log(456);
            }
        }

10.原型链

 

 

        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        Star.prototype = {
            constuctor: Star,
            sing: function() {
                console.log(123);
            },
            dance: function() {
                console.log(456);
            }
        }
        var ldh = new Star('ldh', '234'); // 新建实例对象
        Object.prototype.sex = 'nan'; // 按照原型链的查找机制,则先找实例对象本身的成员,再按照原型链往上找,都没有就返回空
        Star.prototype.sex = 'nv';
        console.log(ldh.sex); // 结果:nv

11.this指向问题

        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        var that;
        Star.prototype.sing = function() {
            console.log(123);
            that = this;
        }
        var ldh = new Star('ldh', '234'); // 新建实例对象
        ldh.sing();
        console.log(that == ldh); // 结果:true

原型对象函数里的this指向的是实例对象。

12.扩展内置对象方法

给数组原型对象添加一个求和的方法。

 Array.prototype.sum = function() {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i];
            }
            return sum;
        }
        var arr = [12, 4, 6, 7, 4, 3];
        console.log(arr.sum());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值