当我将原型分配给功能时,我得到了不希望的输出

时间:2015-09-02 12:53:07

标签: javascript

请按照以下代码

var fn79 = function(){

    var Student = function(_name){
        this.name = _name;
    };


    Student.prototype = function(){
        print("Inside Prototype function");
    };


    //Student.prototype = {}

    var obj1 = new Student("Ricky");

    Student.prototype.lastName = "Gonzales";

    var obj2 = new Student("Jacky");

    print(obj1.name+" - "+obj1.lastName);
    print(obj2.name+" - "+obj2.lastName);   
};

fn79();

我得到的输出是

D:\Rahul Shivsharan\MyPractise\JavaScriptCommandLine>java -jar js-14.jar prac.js
- Gonzales
- Gonzales

D:\Rahul Shivsharan\MyPractise\JavaScriptCommandLine>

从上面的输出中你可以看到我无法打印对象的“名称”属性。

现在,如果我将代码更改为如下,

    var fn79 = function(){

    var Student = function(_name){
        this.name = _name;
    };

    /*
    Student.prototype = function(){
        print("Inside Prototype function");
    };
    */

    Student.prototype = {}

    var obj1 = new Student("Ricky");

    Student.prototype.lastName = "Gonzales";

    var obj2 = new Student("Jacky");

    print(obj1.name+" - "+obj1.lastName);
    print(obj2.name+" - "+obj2.lastName);   
};

fn79();

我得到了所需的输出

D:\Rahul Shivsharan\MyPractise\JavaScriptCommandLine>java -jar js-14.jar prac.js
Ricky - Gonzales
Jacky - Gonzales

D:\Rahul Shivsharan\MyPractise\JavaScriptCommandLine>

为什么我的第一个例子无法正常工作。

函数是javascript中的一个对象。

我的想法是,

Student.prototype = function(){
       print("Inside Prototype function");
}

学生的原型指向的功能本身就是一个对象。

那么为什么“名字”在我的第一个案例中没有打印出来,以及原型分配到功能如何影响它。

4 个答案:

答案 0 :(得分:0)

您似乎对原型是什么以及如何使用它们有误解。我将重构您的代码并告诉您为什么它的工作方式以及如何使用它们的一般共识:

您声明了一个函数 - 这称为Constructor函数。它将构造所有变量等。

function Student(firstname, lastname){
    this.firstname = firstname;
    this.lastname = lastname;
}

您的原型是keysvalues的对象。这只是因为你的原型不会存在于实际产品上,它会像 on 元素一样(而不是在element.prototype中)。我们将会这样做,但是现在你应该记住,变量最好在上面的构造函数中声明,而方法在原型中是最好的。你可以将它们混合起来,但它很容易划分,它可以保持你的代码清晰。

Student.prototype = {
    showName: function(){ return this.firstname + ' ' + this.lastname; }
};

现在,当我们构建学生实例时,我们可以使用方法showName

var gonzales = new Student('Johny','Gonzales');
console.log(gonzales.showName()); // 'Johny Gonzales'

另请注意,我们未在构造对象上提及原型。它仍然在__proto__中“可用”,因为它是继承的......但从正常的角度来看,这并不重要。

变量也可以通过简单的点符号直接访问。顺便说一句,请记住,变量和方法共享相同的命名空间!

console.log(gonzales.firstname); // Johny

您不能将原型设置为函数本身(除非它是一个返回对象的自执行函数)。 javascript中的Functions虽然被认为是对象,但却是具有各自魔力的不同野兽 - 不要将它们视为对象,因为它们不会善待它们。不要试图这样做,因为它可以打破一些Javascript继承,并将创建无法阻止的无数错误。

有关详细信息和准确命名,请参阅此文章:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Custom_objects

答案 1 :(得分:0)

函数的问题在于它们具有不可写的.name属性。这种不可写性甚至会影响从函数继承的对象,在您的情况下是Student实例,因此赋值失败:

var Student = function(name){
    console.log(this.name);
    this.name = name;
    console.log(this.name);
};
Student.prototype = function ProtoName() {};
console.log(Student.prototype.name);
new Student("test");

你只会看到字符串"ProtoName"三次。

您可以使用strict mode使.name =失败更明显:

var Student = function(name){
    "use strict";
    this.name = name;
};
Student.prototype = function ProtoName() {};
new Student("test");

您将获得Error: Invalid assignment in strict mode

您可以使用Object.defineProperty而不是简单赋值在.name实例上创建Student属性来解决不可写问题,但实际上您不应该使用函数对象作为原型。

答案 2 :(得分:-1)

虽然JS中的函数最终也是一个Object,但它的反面方式不同,因为这意味着每个Object也是一个函数。

原型Object包含原型所具有的所有功能。这对于Object继承等非常重要。

如果你回想一下记忆架构,它就是这样的:

{
    hi : function hi(){}, // pointer to the function 'hi'
    bye : function bye(){}, // pointer to function 'bye'
    data : { planet : 'earth' } // pointer to an Object with a pointer to a String which contains 'earth'
}

如果用一个函数覆盖Object,它就会全部死掉 主要是因为JS知道'一个对象原型应该包含函数或其他对象,并且不会执行'原型对象本身。

所以基本上,它更像是一个JS使用的索引来查找你在课堂上可能需要或不需要的东西。实例

答案 3 :(得分:-1)

当您设置Student对象的原型时:

Student.prototype = function(){
     print("Inside Prototype function");
};

Student的原型将是@somethinghere指出的这个简单函数,(而不是包含函数constructor和对象__proto__),所以所有的属性并删除Student的功能。这就是删除属性name的原因。

当您将第二个属性lastname添加到Student时:

Student.prototype.lastName = "Gonzales";

Student的原型现在具有属性lastname

正如@somethinghere所指出的那样:

  

学生的每个实例现在都会分享姓氏

More informations about the prototype of an Object