资讯专栏INFORMATION COLUMN

js构造函数

vpants / 1095人阅读

摘要:今年岁了调用私有方法实例化张三此时实例获取不到方法追更感谢之染的评论,构造函数还可以通过来添加对象栗子实例化张三此时实例化后的对象拥有方法输出张三关于构造函数的继承可以看一下我的下一篇文章构造函数继承方法及利弊

js构造函数

前言:之前看过公司大神的代码,发现有很多构造函数,类似Java和C#的 new 方法来实例化一个对象,感觉很是受教,刚好最近在用es6,发现了用class来实现构造函数,于是总结了一下,也是回顾和提高的过程,由于本人也是前端小白,文章可能有很多错误,欢迎各位大神批评指正~~

传统ES5语法
    // 常规方法一
    function Persion(name, age) {
        this.name = name;                // this.key 赋值,则直接挂载到Persion实例
        this.age = age;
        this.getInfo = function() {
            return {
                name: this.name,
                age: this.age
            }
        }
    }
    // 调用
    var persion = new Persion("张三", 15);
    // 此时的persion实例拥有name、age、getInfo()三个属性及方法

    // 常规方法二
    function Persion(name, age) {
        var name = name;
        var age = age;
        var getInfo = function() {
            return {
                name: name,
                age: age,
            }
        }
        return { // 通过return将元素暴露给实例对象
            name: name,
            age: age,
            getInfo: getInfo,
        }
    }
    // 调用 
    var persion = new Persion("张三", 15);
    // 此时的persion实例拥有name、age、getInfo()三个属性及方法
ES6
class Persion {
    constructor(name, age) { // 一个类必须有constructor方法, 如果没有显式定义, 一个空的constructor方法会被默认添加。
        this.name = name;
        this.age = age;
    }
    getInfo() {
        return {
            name: this.name,
            age: this.age,
        }
    }
}
// 调用
const persion = new Persion("张三", 17);
// 此时的persion实例拥有name、age、getInfo()三个属性及方法

注:ES6 class 声明构造函数会将所有内部元素暴露出来,但有的时候我们希望这些方法只在内部声明时使用,并不暴露给实例对象,在ES5中我们可以很方便的做到,如下栗子:

    // ES5 实现私有方法
    // 方案一
    function Persion(name, age) {
        this.name = name;
        this.age = age;
        var print = function(){
            return name + "今年" + age + "岁了!";
        }
        this.setName = function(newName){
            this.name = newName;
        }
        this.setAge = function(newAge){
            this.age = newAge;
        }
        this.getInfo = function(){
            {
                name: name,
                age: age,
            }
        }
        this.printInfo = function(){
            console.log(print());
        }
    }
    // 实例化
    var persion = newPersion("张三", 15);
    
    // 方案二
    function Persion(name, age) {
        var name = name,
            age = age;
        // print作为私有方法,只在内部用于生成输出字符串,并不需要暴露到外部
        var print = function(){
            return name + "今年" + age + "岁了!";
        }
        var setName = function(newName){
            name = newName;
        }
        var setAge = function(newAge){
            age = newAge;
        }
        var getInfo = function(){
            {
                name: name,
                age: age,
            }
        }
        var printInfo = function(){
            console.log(print());
        }
        return {
            name: name,
            age: age,
            setName: setName,
            setAge: setAge,
            getInfo: getInfo,
            printInfo: printInfo,
        }
    }
    // 实例化
    var persion = newPersion("张三", 15);
    // 此时实例化的persion 将不会暴露出print方法,我个人更倾向于方案二的方法,可以清楚的看出哪些属性和方法需要暴露出来,也容易修改需要暴露的接口。

那么在ES6中我们要怎么实现私有的方法和属性呢?其实方法很多,但都很不友好,我只总结了三种,如果有什么好的方法欢迎大家给我留言,不胜感激:)

// 私有方法 变通方案
// 方案一 (其实并不算一个方法。。。)
class Persion {
    constructor(name, age) { 
        this.name = name;
        this.age = age;
    }
    _print() { // 通常以“_”开头命名的方法为内部私有方法
        return name + "今年" + age + "岁了!";
    }
    setName(newName) {
        this.name = newName;
    }
    setName(newAge) {
        this.age= newAge;
    }
    printInfo() {
        console.log(_print());
    }
    getInfo() {
        return {
            name: this.name,
            name: this.age,
        }
    }
}
// 实例化
const persion = new Persion("张三", 15);
// 此时persion实例仍然能获取到_print方法,只能用来区分私用和公有方法而已;

// 方案二
// 注意若使用ES6箭头函数则this指向的是该方法本身,而非调用它的对象,
function _print() { // 外部声明_print 方法,在内部调用,此时_print 成为Persion类的私有方法
    return this.name + "今年" + this.age + "岁了!";
}
class Persion {
    constructor(name, age) { 
        this.name = name;
        this.age = age;
    }
    setName(newName) {
        this.name = newName;
    }
    setName(newAge) {
        this.age= newAge;
    }
    printInfo() {
        console.log(_print());
    }
    getInfo() {
        return {
            name: this.name,
            name: this.age,
        }
    }
}
// 实例化
const persion = new Persion("张三", 15);
// 此时persion实例获取不到_print方法;
    
// 方案三
const print = Symbol("print"); // 声明一个Symbol值,用来做为私有方法的名字
class Persion {
    constructor(name, age) { 
        this.name = name;
        this.age = age;
    }
    setName(newName) {
        this.name = newName;
    }
    setName(newAge) {
        this.age= newAge;
    }
    [bar]() {  // 将私有方法的名字命名为一个Symbol值。
        return this.name + "今年" + this.age + "岁了!";
    }
    printInfo() {
        console.log([bar]()); // 调用私有方法
    }
    getInfo() {
        return {
            name: this.name,
            name: this.age,
        }
    }
}
// 实例化
const persion = new Persion("张三", 15);
// 此时persion实例获取不到[bar]方法;

# 追更
感谢 @黒之染 的评论, 构造函数还可以通过prototype来添加对象

栗子:
```
function Persion(name, age){
    this.name = name,
    this.age = age,
}
Persion.prototype.getInfo = function(){
    return {
        name: this.name,
        age: this.name,
    }
}
// 实例化
var persion = new Persion("张三");
// 此时实例化后的对象persion拥有getInfo()方法
persion.getInfo() // 输出{name: "张三"}
```

关于js构造函数的继承可以看一下我的下一篇文章js构造函数(继承方法及利弊)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95593.html

相关文章

  • JS基础(对象创建,构造函数、原型、实例之间关系,继承方式)

    摘要:对象创建的三种方式字面量创建方式系统内置构造函数方式自定义构造函数构造函数原型实例之间的关系实例是由构造函数实例化创建的,每个函数在被创建的时候,都会默认有一个对象。 JS 对象创建的三种方式 //字面量创建方式 var person= { name:jack } //系统内置构造函数方式 var person= new Object(); person.name = jack; ...

    PAMPANG 评论0 收藏0
  • JS 原型的解释

    首先明确两个概念: 构造函数和 instance 分别是什么 构造函数JS 中并没有在语法层面上面区分构造函数和普通函数, 唯一的区别是调用方式使用 new 调用的函数就是构造函数, 没有则是普通函数. 实例new Constructor() 返回的对象称为 Constructor 的一个实例 然后提出一个规则:在构造函数的原型上面附加的属性或者方法, 可以被其所有的实例共用. 可以推导出: ...

    silvertheo 评论0 收藏0
  • JS面向对象编程之封装

    摘要:在基于原型的面向对象方式中,对象则是依靠构造函数和原型构造出来的。来看下面的例子优点与单纯使用构造函数不一样,原型对象中的方法不会在实例中重新创建一次,节约内存。 我们所熟知的面向对象语言如 C++、Java 都有类的的概念,类是实例的类型模板,比如Student表示学生这种类型,而不表示任何具体的某个学生,而实例就是根据这个类型创建的一个具体的对象,比如zhangsan、lisi,由...

    YFan 评论0 收藏0
  • JS高级程序设计》读书笔记----JS创建对象的七种模式

    摘要:用对象字面量形式创建的对象,直接赋值给函数的原型对象,本质上完全重写了其对象,因此属性也就变成了新对象的属性指向构造函数,不再指向函数。 【上一篇】:JavaScript对象内部属性及其特性总结 showImg(https://segmentfault.com/img/bVbjYsc?w=839&h=489); 工厂模式(★★) 先在内部显示地创建一个临时对象,根据接收的参数来构建(赋...

    Dogee 评论0 收藏0
  • JavaScript面向对象

    摘要:构造函数的两个特征函数内部使用了,指向所要生成的对象实例。将一个空对象的指向构造函数的属性,这个对象就是要返回的实例对象。用面向对象开发时,把要生成的实例对象的特有属性放到构造函数内,把共有的方法放到构造函数的里面。 JS中面向对象的概念 面向对象OOP是一种组织代码结构、实现功能过程的思维方式。它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的...

    Eirunye 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<