JS 中的类Public,Private 和 Protected详解

目录
  • 前言
  • public
  • private
  • protected

前言

原文地址:dev.to/bhagatparwi…

即使 ES6 中引入了 class 关键字很好的模拟了类的行为以及使我们可以进行面向对象编程,但 JavaScript 中的类缺失了创建公共、私有和保护成员的能力。

若你之前使用过其他面向对象的编程语言,肯定知道内部和外部接口的重要性。内部接口引用的方法和属性只能在类的内部获取。相反,外部接口的方法和属性可以在内外部都可获取。

主要有三个关键字在起作用:public、protected 和 private。

  • public:类的所有成员都可以被类的实例获取。
  • private:类成员只能在类中被访问。
  • protected:类成员在类以及子类中可以被访问

在 JavaScript 中 protected 关键字是最难模拟的。

public

publick 是 JavaScript 中默认的,如果从对象上可以获取的东西,那也可以从它的实例上获取。

const myObject = {
    name: "Parwinder",
    sayMyName: function () {
        return this.name;
    }
}

console.log(myObject.name); // Parwinder
console.log(myObject.sayMyName()); // Parwinder

上面的例子中,我可以获取属性和方法不会产生任何问题,若你更倾向类语法:

class ObjectCreator {
    name;

    constructor(name) {
        this.name = name;
    }
    sayMyName() {
        return this.name;
    }
}
const myObject = new ObjectCreator("Parwinder");
console.log(myObject.name); // Parwinder
console.log(myObject.sayMyName()); // Parwinder

private

JavaScript 中有很多方法创建私有变量,第一个是闭包:

function carMonitor() {
    var speed = 0;

    return {
        accelerate: function () {
            return speed++;
        }
    }
}
var car = new carMonitor();
var redCar = new carMonitor()
console.log(car.accelerate()); // 0
console.log(car.accelerate()); // 1
console.log(redCar.accelerate()); // 0
console.log(redCar.accelerate()); // 1
console.log(car.accelerate()); // 2
console.log(redCar.accelerate()); // 2
console.log(speed); // speed is not defined

car 和 redCar 各自维护它们自己的 speed 变量并且外部无法获取它。在构造函数或类中,我们强制用户通过方法来获取属性而不是直接读写。这也就是如何封装代码。

第二个方法就是使用 # 符号。

class ObjectCreator {
    #meaningOfLife;

    constructor(name) {
        this.#meaningOfLife = 42;
    }

    returnMeaningOfLife() {
        return this.#meaningOfLife;
    }

    #returnAMessage() {
        return "You will do great things in life";
    }
}

const myObject = new ObjectCreator("Parwinder");
console.log(myObject.returnMeaningOfLife()); // 42
console.log(myObject["#meaningOfLife"]); // undefined
console.log(myObject.#meaningOfLife); // SyntaxError
console.log(myObject.#returnAMessage); // SyntaxError

从语言层面强制封装了代码,外部直接获取 # 引用的字段则会报错。public 和 private 字段同时存在不会冲突,在同一个类中既可以有私有的 #meaningOfLife 也可以有公共的 meaningOfLife。

类中使用 # 符号来声明私有成员是在 ES2019/ES10 中引入的。

protected

就像我前面说的在 JavaScript 中 protected 是三个方法中最难实现的。我能想到的途径是通过只存在 getter 而没有 setter 的方法来实现 protected 。

若你有别的方法实现,请分享一下!

class NameGenerator {
    _name;

    constructor(name) {
        this._name = name;
    }

    get name() {
        return this._name;
    }
}

let nameGenerator = new NameGenerator("John");
console.log(`My name is ${nameGenerator.name}`); // My name is John
nameGenerator.name = "Jane"; // Cannot assign to 'name' because it is a read-only property.

到此这篇关于JS 中的类Public,Private 和 Protected详解的文章就介绍到这了,更多相关JS Public,Private ,Protected内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • javascript中定义私有方法说明(private method)

    一度以为在javascript的世界里,所有方法都是公有的,无法真正从技术上定义一个私有方法,今天又一次发现:其实我错了! 复制代码 代码如下: var Person = function(name,sex){     this.name = name;     this.sex = sex;          var _privateVariable = "";//私有变量         //构造器中定义的方法,即为私有方法     function privateMethod()

  • JavaScript的public、private和privileged模式

    Summary 私有变量 在对象内部使用'var'关键字来声明,而且它只能被私有函数和特权方法访问. 私有函数 在对象的构造函数里声明(或者是通过var functionName=function(){...}来定义),它能被特权函数调用(包括对象的构造函数)和私有函数调用. 特权方法 通过this.methodName=function(){...}来声明而且可能被对象外部的代码调用.它可以使用:this.特权函数() 方式来调用特权函数,使用 :私有函数()方式来调用私有函数. 公共属性 通

  • JS中的public和private对象,即static修饰符

    复制代码 代码如下: //重新封装document对象 var Console={ Write:function(msg){alert(msg);} }; //Person对象 var Person={ _name:"zzl", //static public _age:28, PrintInfo:function(){Console.Write("name:"+Person._name+",age:"+this._age);} //public

  • JS 中的类Public,Private 和 Protected详解

    目录 前言 public private protected 前言 原文地址:dev.to/bhagatparwi… 即使 ES6 中引入了 class 关键字很好的模拟了类的行为以及使我们可以进行面向对象编程,但 JavaScript 中的类缺失了创建公共.私有和保护成员的能力. 若你之前使用过其他面向对象的编程语言,肯定知道内部和外部接口的重要性.内部接口引用的方法和属性只能在类的内部获取.相反,外部接口的方法和属性可以在内外部都可获取. 主要有三个关键字在起作用:public.protec

  • PHP中Closure类的使用方法及详解

    Closure,匿名函数,又称为Anonymous functions,是php5.3的时候引入的.匿名函数就是没有定义名字的函数.这点牢牢记住就能理解匿名函数的定义了. Closure 类(PHP 5 >= 5.3.0)简介 用于代表 匿名函数 的类. 匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象,下面我们来看一下PHP Closure类的使用方法及介绍. PHP Closure类之前在PHP预定义接口中介绍过,但它可不是interface哦,它是一个内部的final类.Clo

  • JS中实现浅拷贝和深拷贝的代码详解

    (一)JS中基本类型和引用类型 JavaScript的变量中包含两种类型的值:基本类型值 和 引用类型值,在内存中的表现形式在于:前者是存储在栈中的一些简单的数据段,后者则是保存在堆内存中的一个对象. 基本类型值 在JavaScript中基本数据类型有 String , Number , Undefined , Null , Boolean ,在ES6中,又定义了一种新的基本数据类型 Symbol ,所以一共有6种. 基本类型是按值访问的,从一个变量复制基本类型的值到另一个变量后,这两个变量的值

  • Java中BigDecimal类的add()的使用详解

    Java中的BigDecimal类的使用: 使用Java中的BigDecimal可以进行精确的计算,但是在使用BigDecimal时我们需要注意它的add()方法,使用它自身的add( )方法并不会改变它原始的值,因为初始化BigDecimal是创建一个了个对象,使用add()方法时也等于是创建了一个对象,若要保存这个对象需要再创建一个对象. 句法: public BigDecimal add(BigDecimal val); public BigDecimal add(BigDecimal v

  • js中的关联数组与普通数组详解

    var privArr = []; privArr['staProjQueryGrid'] = [{ btn_id : 'but_add', roles : ['2001','2005'] }] console.log(privArr,privArr.staProjQueryGrid[0].btn_id) 第一行是定义一个数组priArr,第二行是给这个数组添加一个属性staProjQueryGird,这个属性值是一个数组.打印结果是  but_add var unPrivArr = [];//

  • JS中正则表达式全局匹配模式 /g用法详解

    本文章来详细介绍js中正则表达式的全局匹配模式 /g用法,代码如下: var str = "123#abc"; var re = /abc/ig; console.log(re.test(str)); //输出ture console.log(re.test(str)); //输出false console.log(re.test(str)); //输出ture console.log(re.test(str)); //输出false 在创建正则表达式对象时如果使用了"g&q

  • JS中的hasOwnProperty()和isPrototypeOf()属性实例详解

    这两个属性都是Object.prototype所提供:Object.prototype.hasOwnProperty()和Object.prototype.isPropertyOf() 先讲解hasOwnProperty()方法和使用.在讲解isPropertyOf()方法和使用 看懂这些至少要懂原型链 一.Object.prototype.hasOwnProperty() 概述 hasOwnProperty()方法用来判断某个对象是否含有指定的自身属性 语法 obj.hasOwnPropert

  • JS中对象与字符串的互相转换详解

    在使用 JSON2.JS 文件的 JSON.parse(data) 方法时候,碰到了问题: throw new SyntaxError('JSON.parse'); 查询资料,大概意思如下: JSON.parse方法在遇到不可解析的字符串时,会抛出SyntaxError异常. 即:JSON.parse(text, reviver),This method parses a JSON text to produce an object or array. t can throw a SyntaxE

  • 基于js中style.width与offsetWidth的区别(详解)

    作为一个初学者,经常会遇到在获取某一元素的宽度(高度.top值...)时,到底是用 style.width还是offsetWidth的疑惑. 1. 当样式写在行内的时候,如 <div id="box" style="width:100px">时,用 style.width或者offsetWidth都可以获取元素的宽度. 但是,当样式写在样式表中时,如 #box{ width: 100px; }, 此时只能用offsetWidth来获取元素的宽度,而sty

  • 基于vue.js中事件修饰符.self的用法(详解)

    .self可以理解为跳过冒泡事件和捕获事件,只有直接作用在该元素上的事件才可以执行. 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>self</title> <script src="vue.js"></script> <!--'''''''

随机推荐