【问题标题】:JavaScript Inherited Properties Default ValueJavaScript 继承的属性默认值
【发布时间】:2013-10-04 04:50:45
【问题描述】:

考虑下面的代码

function Employee() {
    this.id = "";
    this.name = "";
    this.gender = "";
}

function Programmer() {
    this.expertise = "";
}

Programmer.prototype = new Employee();

然后我想将 Programmer 进一步继承给 JScriptProgrammer,并将默认值“expertise”设置为“JavaScript”。

问题: 有什么区别

function JScriptProgrammer() {
    this.expertise = "JavaScript";
}

JScriptProgrammer.prototype = new Programmer();

function JScriptProgrammer() {
}

JScriptProgrammer.prototype = new Programmer();
JScriptProgrammer.prototype.expertise = "JavaScript";

【问题讨论】:

标签: javascript


【解决方案1】:

您可以使用原型作为对象的默认值,它确实可以节省内存。如果您以后不确定该属性(在实例上为其分配一个新值),那么所有实例共享指向该值的相同指针。

如果你确定要为其赋值,那么最好在构造函数主体中将其定义为this.myval

这是为原型分配默认值的棘手部分;您必须重新为其分配一个新值才能进行特定于实例的更改。对象值可以通过调用它们的函数或重新分配属性来操作。当您这样做时,所有实例的默认值都会更改:

var Person=function(){};
Person.prototype.teeth=[0,1,2,3];
Person.prototype.legs={left:1,right:1};

var ben=new Person();
var betty=new Person();
ben.teeth.splice(2,1);//ben looses a tooth
//when ben looses a tooth like that betty looses it too
console.log(betty.teeth);//[1,2,3] poor betty
//now poor betty has an accident
betty.legs.right=0;
//looks like ben looses it too
console.log(ben.legs);//{left:1,right:0}
//I don't feel sorry for ben though because
//he knocked out betty's tooth

继承最好不要发起新的实例,可以使用Object.create或者辅助函数来设置继承而不创建实例。所有关于继承、原型、覆盖和调用 super 的内容都在这里:https://stackoverflow.com/a/16063711/1641941

【讨论】:

  • 太棒了!所以使用原型来定义属性的默认值是不好的,因为它将成为对象所有实例的共享成员。谢谢!!真的很感谢答案! :)
  • @ch0eb1t 不客气。在谷歌闭包库中,所有原始值都在原型上定义。所以字符串、数字和布尔值都可以。可以使用对象,但你永远不能操纵它们,总是重新分配以改变它的价值。当您的代码被其他程序员共享时,他们可能不知道这一点并得到意想不到的结果,因此对于需要特定于实例的对象成员,我不会在原型上指定它们。
【解决方案2】:

区别

function JScriptProgrammer() {
this.expertise = "JavaScript";
}
JScriptProgrammer.prototype = new Programmer();

表示当您使用 JScriptProgrammer() 时,专家值已设置为“JavaScript”

但是当你使用时

function JScriptProgrammer() 
{
}
JScriptProgrammer.prototype = new Programmer();
JScriptProgrammer.prototype.expertise = "JavaScript";

表示您在使用 JScriptProgrammer() 后设置了专业值

【讨论】:

  • 我认为这不是一个有效的答案。请参阅jsbin.com/OQEBaHu/1/edit 日志输出“JavaScript”而不是“Not JavaScript”。如果使用原型将在构造函数调用后设置值,则示例中的日志输出必须是“Not JavaScript”而不是“JavaScript”
【解决方案3】:

它们是相同的。第二个版本节省了内存,这意味着所有的孩子都使用相同的函数/变量实例。

请参阅以下示例,说明为什么可能需要 this

function JScriptProgrammer() {
   var tmp = "Hello";

   //accessing private variables
   this.sayHello = function() {
      alert(tmp + " "+ this.expertise + "er");
   }
}

JScriptProgrammer.prototype = new Programmer();
JScriptProgrammer.prototype.expertise = "JavaScript";

更多阅读

【讨论】:

    【解决方案4】:

    在简历中:

    prototype 用于继承现有对象。例如。如果你想为 Array 对象添加一个新方法,你可以这样做

    Array.prototype.MyNewMethod = function()
    {
    alert("im bellow to array object")
    }
    

    这意味着你可以这样做

    var array = [1,2,3];
    array.MyNewMethod();//prints im bellow to array object
    

    (read this post for more reference)

    这意味着你的代码正在这样做:

            function JScriptProgrammer() {
            }
            function Programmer(){
            this.name = "hello world";
           }
            JScriptProgrammer.prototype = new Programmer();// inhering from Programmers object(or lets say class)
            JScriptProgrammer.prototype.expertise = "JavaScript"; // assigning a value to expertise property that belows to JScriptProgrammer class
    
    
    
    console.log(new JScriptProgrammer())//JScriptProgrammer {name: "hello world", expertise: "JavaScript"} notice that property name that bellow to Programmer
     object now is in JScriptProgrammer object as well. 
    

    这里测试http://jsbin.com/IgOFimi/1/edit

    【讨论】:

    • 我不知道这应该回答什么,但代码并没有真正展示任何东西。
    • @Misters:很抱歉,但我要问的是分配对象默认值的区别。同时使用 this.expertise 和 prototype.expertise 就可以了。我只想知道这两者之间的区别。显然,肯定有这样一种情况,使用 this 更受青睐,或者使用原型更受青睐。
    猜你喜欢
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 2018-06-07
    • 2013-01-05
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    相关资源
    最近更新 更多