Javascript有没有 类 基于类的对象模型。它使用强大的原型继承,可以模仿类,但不太适合。一切都是对象,对象[可以]从其他对象继承。
构造函数只是一个将属性分配给新创建的对象的函数。可以通过关键字(在函数本地)引用对象(通过使用
new关键字的调用创建)。
this
方法也只是在对象上调用的函数-
再次
this指向该对象。至少当使用成员运算符(点,括号)将该函数作为对象的属性调用时。这给新手带来了很多困惑,因为如果您传递该函数(例如,传递给事件侦听器),则该函数与访问该对象的对象“分离”。
现在继承在哪里?“类”的实例继承自相同的原型对象。方法被定义为该对象上的函数属性(而不是每个实例的一个函数),调用它们的实例只是继承该属性。
例:
function Foo() { this.bar = "foo"; // creating a property on the instance}Foo.prototype.foo = 0; // of course you also can define other values to inheritFoo.prototype.getBar = function() { // quite useless return this.bar;}var foo = new Foo; // creates an object which inherits from Foo.prototype, // applies the Foo constructor on it and assigns it to the varfoo.getBar(); // "foo" - the inherited function is applied on the object and // returns its "bar" propertyfoo.bar; // "foo" - we could have done this easier.foo[foo.bar]; // 0 - access the "foo" property, which is inheritedfoo.foo = 1; // and now overwrite it by creating an own property of foofoo[foo.getBar()]; // 1 - gets the overwritten property value. Notice that(new Foo).foo; // is still 0
因此,我们仅使用该对象的属性并对它感到满意。但是所有这些都是“公开的”,并且可以被覆盖/更改/删除!如果那没关系,那么您很幸运。您可以通过在属性名称前加下划线来表示属性的“私有性”,但这只是对其他开发人员的提示,可能不会被遵守(特别是错误的)。
因此,聪明的人找到了一种使用构造函数作为闭包的解决方案,从而允许创建私有的“属性”。javascript函数的每次执行都会为局部变量创建一个新的变量环境,执行完成后可能会收集垃圾。在该范围内声明的每个函数也都可以访问这些变量,并且只要可以调用这些函数(例如,通过事件侦听器),环境就必须持久。因此,通过从构造
函数中导出本地定义的函数,您可以使用只能由这些函数访问的局部变量来保留该变量环境。
让我们来看看它的作用:
function Foo() { var bar = "foo"; // a local variable this.getBar = function getter() { return bar; // accesses the local variable }; // the assignment to a property makes it available to outside}var foo = new Foo; // an object with one method, inheriting from a [currently] empty prototypefoo.getBar(); // "foo" - receives us the value of the "bar" variable in the constructor
现在,在构造函数内部定义的此getter函数称为“ _特权
方法”,因为它可以访问“私有”(本地)“属性”(变量)。的价值
bar永远不会改变。当然,您也可以为其声明一个setter函数,并可以添加一些验证等。
注意,原型对象上的方法无权访问构造函数的局部变量,但它们可能使用特权方法。让我们添加一个:
Foo.prototype.getFooBar = function() { return this.getBar() + "bar"; // access the "getBar" function on "this" instance}// the inheritance is dynamic, so we can use it on our existing foo objectfoo.getFooBar(); // "foobar" - concatenated the "bar" value with a custom suffix
因此,您可以将两种方法结合起来。请注意,特权方法需要更多的内存,因为您创建具有不同作用域链(但代码相同)的不同功能对象。如果要创建大量实例,则应仅在原型上定义方法。
当您设置从一个“类”到另一个“类”的继承时,它会变得更加复杂-基本上,您必须使子原型对象从父类继承,并将父构造函数应用于子实例以创建“私有属性”
”。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)