TS学习笔记04 JS创建对象的方式

TS学习笔记04 JS创建对象的方式

​ 首先我们回顾下JS中创建对象的方式

​ 比如说我按照下面的创建了两个对象分别为stu1和stu2,比如说我现在想给这两个对象都添加一个新的方法,但是这两个对象都分别独立的,只能一个个添加。无法通过prototype添加共享功能。

/**
 * 回顾一:JS中定义对象的几种方式
 *  优点:简单、方便
 *  缺点:只能描述一个对象的结构,无法为多个对象添加共享的原型功能
 * 
 */

方式一:对象字面量

 var stu1 = {
    name:'tom',
    age:18,
    study:function(){
        console.log('正在学习。。。。');
    }
}

// 没有原型,无法通过prototype添加共享功能
// stu1.prototype.show = function(){
//     console.log('自我介绍');
// }

var stu2 = {
    name:'alice',
    age:20
}

console.log(stu1.name,stu1.age);
stu1.study();
stu1.show();//会报错,Cannot not set property 'show' of underfind

方式2:构造函数/构造器

/**
 * 方式2:构造函数/构造器
 *  优点:基于同一个构造函数创建对象,多个对象具有相同的结构,可以添加共享和原型功能
 *  缺点:无法为构造函数提供独立的作用域
 */
 //如果需要添加元素,在构造函数里面添加,其余的对象都会读到这个元素
 function Student(name,age){
    this.name = name; // this表示将来new出来的当前对象
    this.age = age;
    this.study = function(){
        console.log('正在学习。。。。');
    }
}

//new一个新的对象,这个对象名对应的就是上述构造器的.this,比如this.name实际上就是str1.name
var str1 = new Student('tom',18);

// 通过原型的方式添加功能
Student.prototype.sex = 'male';
Student.prototype.show = function(){
    console.log('自我介绍:'+this.name+','+this.age+','+this.sex);
    console.log(data);
}
stu1.show(); //output:自我介绍:tom,18,male

构造函数中的属性 和原型中的属性 有什么不同?

​ 我们先new两个实例。

function Student(name,age){
    this.name = name; // this表示将来new出来的当前对象
    this.age = age;
    this.study = function(){
        console.log('正在学习。。。。');
    }
}
Student.prototype.sex = 'male';
Student.prototype.show = function(){
    console.log('自我介绍:'+this.name+','+this.age+','+this.sex);
    console.log(data);
}

var stu1 = new Student('tom',18);
var stu2 = new Student('alice',20);
console.log(stu1)
console.log(stu2)

打印后的结果如图:

image-20220126144844280

image-20220126144925805

我在上述的代码中,通过原型的方式添加了一个属性sex为male,这个属性属于原型的,属于全局的。而new出来的age和name属性属于实例属性,这两者是不一样的。

观察下面的代码,我把stu1添加一个属性,再同时打印stu1和stu2。

可以明显看到,stu1中多了一个属性(stu1原本不具有这个属性),但是原型中的sex依旧是male。

stu1.sex = 'female'; // 为stu1添加一个实例属性sex,并不是修改原型中的属性

image-20220126145833139

那么如何修改原型中的属性呢?

首先我们需要找到原型。可以看出在[[Prototype]]这个属性里面包裹的是原型。

image-20220126150215428

修改原型,再次打印出来后发现原型被成功的修改了。

stu1.__proto__.sex = 'female';

image-20220126150508562

并且再次打印stu2,发现stu2的原型也同样被修改了。

image-20220126150712100

总结就是:

​ 构造函数中的属性:每个实例都有独立的属性,互不影响;

​ 原型中的属性:所有实例所共享,访问的是同一个值。

方式三:闭包构造函数

​ 通过自执行函数 (function(){})() 将构造函数和原型定义包裹起来,构造一个独立作用域

// 定义一个变量Student来接受这个自执行函数返回的结果
var Student = (function(){
//  这个data是定义在这个函数里面的,所以函数外面是访问不了的,这就解决了方法二无法为构造函数提供独立的作用域的痛点
    var data = 'hello'; // 全局作用域
    function Student(name,age){
        this.name = name; // this表示将来new出来的当前对象
        this.age = age;
        this.study = function(){
            console.log('正在学习。。。。');
        }
    }

    // 通过原型的方式添加功能
    Student.prototype.sex = 'male';
    Student.prototype.show = function(){
        console.log('自我介绍:'+this.name+','+this.age+','+this.sex);
        console.log(data);
    }

    return Student;
})();

var stu1 = new Student('tom',18); 
var stu2 = new Student('alice',20);
stu1.show();//output: tom,18,male       hello
stu2.show();//output: alice,20,male     hello
相关推荐

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

sakuraxiaoyu

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值