[英]declaring protected variable in javascript
我如何声明受保护的变量。 让我在这里举个例子
// Constructor
function Car(){
// Private Variable
var model;
}
// Public variable
Car.prototype.price = "5 Lakhs";
// Subtype
function Indiancar(){
}
// Prototype chaining
Indiancar.prototype = new Car();
// Instantiating Superclass object
var c = new Car();
// Instantiating subclass object
var ic = new Indiancar();
在这个我想有一个变量,它可以作为 ic.variabl 访问,它也存在于汽车类中。
你会做这样的事情:
var Base = function()
{
var somePrivateVariable = 'Hello World';
this.GetVariable = function()
{
return somePrivateVariable;
};
this.SetVariable = function(newText)
{
somePrivateVariable = newText;
};
};
var Derived = function()
{
};
Derived.prototype = new Base();
var instance = new Derived();
alert(instance.GetVariable());
instance.SetVariable('SomethingElse');
alert(instance.GetVariable());
假设我正确理解了你的问题。
编辑:使用真正的“私有”变量进行更新。
有一种方法可以在 JavaScript 中定义受保护的变量:
javascript 中的构造函数可以返回任何对象(不一定是this )。 可以创建一个构造函数,它返回一个代理对象,该对象包含“真实”实例对象的“真实”方法的代理方法。 这听起来可能很复杂,但事实并非如此; 这是一个代码片段:
var MyClass = function() {
var instanceObj = this;
var proxyObj = {
myPublicMethod: function() {
return instanceObj.myPublicMethod.apply(instanceObj, arguments);
}
}
return proxyObj;
};
MyClass.prototype = {
_myPrivateMethod: function() {
...
},
myPublicMethod: function() {
...
}
};
好处是代理创建可以自动化,如果我们定义命名受保护方法的约定。 我创建了一个小库,它就是这样做的: http : //idya.github.com/oolib/
如前所述,javascript 没有受保护的变量。
写完这个问题10年了, Typescript已经成为一种东西,对javascript中的OOP感兴趣的人应该去看看! 它确实支持受保护的变量。
也就是说,我想把我的帽子扔进戒指并提供一种使用普通 javascript 模拟受保护变量的方法,因为这是一个顶级的 Google 搜索结果,并且在撰写本文时投票最多的答案并不符合要求.
// Declare objects within an anonymous function to limit access.
var objectRefs = (function() {
// This is the object we want to inherit from.
function Base(param1, _protected) {
var _public = this;
var _protected = _protected || {};
var _private = {};
// Declare some variables
_public.shared = "Anyone can access this!";
_protected.inherited = "This is protected";
_private.secretVar = "Children cannot access this.";
// Let's try a few functions.
_public.foo = function() {
// We can access protected and private functions here. This would
// not be possible if we attached it to the prototype.
console.log(_protected.inherited);
console.log(_private.secretVar);
_private.secret();
};
_protected.bar = function() {
// One thing to watch out for: private functions called after
// construction do NOT have access to the object via 'this'. This is
// masked by the fact that I assigned it to the '_public' var.
// More reading: https://stackoverflow.com/q/20279484/3658757
console.log(_public.shared);
};
_private.secret = function() {
// The same warning in _protected.bar applies here too.
console.log(_public.shared);
};
}
// Inherits from Base
function Derived(param1, _protected) {
var _public = this;
var _protected = _protected || {};
var _private = {};
// Inherit (ready for the magic?)
Base.call(this, param1, _protected);
// Since we passed a reference to the "_protected" object as an argument
// to the Base object, it has been attaching all of its protected
// variables to it. We can now access those variables here:
// Outputs "This is protected"
console.log(_protected.inherited);
// We can also access protected functions:
_protected.bar();
// We can even override protected variables and functions.
_protected.inherited = "New value!";
// We cannot access private variables belonging to Base.
// This fails:
// console.log(_private.secretVar);
}
// We don't want to allow public access to the constructors, because this
// would let outside code pass in a '_protected' var. Instead, we create new
// objects that accept all params minus '_protected', and inherit from the
// target object.
return {
Base: function(param1) {
Base.call(this, param1);
},
Derived: function(param1) {
Derived.call(this, param1);
}
};
}());
// Assign the constructors to variables for clarity.
var Base = objectRefs.Base;
var Derived = objectRefs.Derived;
// This is how you construct the object.
var newDerived = new Derived("param1");
// Public functions are accessible.
newDerived.foo();
// Protected functions are not. These fail:
// newDerived.bar();
// newDerived.protected.bar();
所以这很有趣! 这种结构使受保护的变量以您期望的方式发挥作用:继承对象可以访问它们,但无法从外部访问它们。
作为参考,上面的代码在 Typescript 中是这样的:
class Base
{
// Declare some variables
public shared: string = "Anyone can access this!";
protected inherited: string = "This is protected";
private secretVar: string = "Children cannot access this.";
constructor(param1: string) {
// We're not using param1; it's only there as an example.
// If we didn't need any constructor code, we could leave this out.
// Note that Typescript has type checking (hence the name)
}
// Let's try a few functions.
public foo(): void {
console.log(this.inherited)
console.log(this.secretVar)
this.secret();
}
protected bar(): void {
console.log(this.shared);
}
private secret(): void {
console.log(this.shared);
}
}
class Derived extends Base {
constructor(param1: string) {
super(param1);
// Outputs "This is protected"
console.log(this.inherited);
// We can also access protected functions:
this.bar();
// We can even override protected variables and functions.
this.inherited = "New value!";
}
}
// This is how you construct the object.
var newDerived = new Derived("param1");
// Public functions are accessible.
newDerived.foo();
// Protected functions are not. This fails:
// newDerived.bar();
在结构上,这要清楚得多。 在编码时,如果您尝试从对象外部访问受保护的变量,则会出现错误。
但请注意:如果您需要编译后的 javascript 来限制对这些变量的外部访问,Typescript 不会为您执行此操作。 编译后的输出如下所示:
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var Base = (function () {
function Base(param1) {
this.shared = "Anyone can access this!";
this.inherited = "This is protected";
this.secretVar = "Children cannot access this.";
}
Base.prototype.foo = function () {
console.log(this.inherited);
console.log(this.secretVar);
this.secret();
};
Base.prototype.bar = function () {
console.log(this.shared);
};
Base.prototype.secret = function () {
console.log(this.shared);
};
return Base;
}());
var Derived = (function (_super) {
__extends(Derived, _super);
function Derived(param1) {
var _this = _super.call(this, param1) || this;
console.log(_this.inherited);
_this.bar();
_this.inherited = "New value!";
return _this;
}
return Derived;
}(Base));
var newDerived = new Derived("param1");
newDerived.foo();
如您所见,不仅受保护的变量是公开的,私有变量也是如此!
如果您需要在浏览器中进行封装,那么您必须坚持使用我在第一段代码中概述的变通方法。 如果您使用封装来帮助您推理代码,那么 Typescript 是您的最佳选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.