Javascript 当我把原型分配给函数时,我得到了不想要的输出

Javascript 当我把原型分配给函数时,我得到了不想要的输出,javascript,Javascript,请按照下面的代码操作 var fn79 = function(){ var Student = function(_name){ this.name = _name; }; Student.prototype = function(){ print("Inside Prototype function"); }; //Student.prototype = {} var obj1 = new Studen

请按照下面的代码操作

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>
从上面的输出可以看出,我无法打印对象的“name”属性

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

    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");
}
学生的原型指向函数本身就是一个对象


那么为什么在我的第一个例子中“name”没有被打印出来,以及原型分配给函数是如何影响它的。

虽然JS中的函数最终也是一个对象是真的,但反过来也不一样,因为这意味着每个对象也是一个函数

prototype对象包含prototype具有的所有功能。这对于对象继承等非常重要

如果回想一下内存模式,它是这样的:

{
    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'
}
如果用函数覆盖对象,则对象将全部失效。
主要是因为JS“知道”对象原型应该包含函数或其他对象,而不“执行”原型对象本身


因此,基本上,它更像是JS使用的一个索引,当您将
学生
对象的原型设置为这样时,可以在类实例中查找您可能需要或不需要的内容:

Student.prototype = function(){
     print("Inside Prototype function");
};
如前所述,
Student
的原型将是这个简单的函数,(而不是包含函数
constructor
和对象
\uuuuuuuuuuuuu
),因此
Student
的所有属性和函数都将被删除。这就是属性
名称
将被删除的原因

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

Student.prototype.lastName = "Gonzales";
Student
的原型现在将具有属性
lastname

如前所述:

学生的每个实例现在都将共享该姓氏


您似乎对什么是原型以及如何使用原型有误解。我将重构您的代码,并告诉您为什么这样做,以及如何使用它们的普遍共识:

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

function Student(firstname, lastname){
    this.firstname = firstname;
    this.lastname = lastname;
}
您的原型是一个具有
的对象。这仅仅是因为您的原型将不存在于实际产品上,它的作用就像它就在元素上一样(而不是在element.prototype中)。我们将谈到这一点,但现在您应该记住,变量最好在上面的构造函数中声明,方法最好在原型中声明。您可以将它们混合使用,但这是一个简单的划分,它可以保持代码清晰

Student.prototype = {
    showName: function(){ return this.firstname + ' ' + this.lastname; }
};
现在,当我们构建student实例时,我们可以使用方法
showName

var gonzales = new Student('Johny','Gonzales');
console.log(gonzales.showName()); // 'Johny Gonzales'
还要注意的是,我们没有提到constructed对象上的原型。它仍然在
\uuuu proto\uuuu
中“可用”,因为它是继承的等等。。。但从正常的角度来看,这并不重要

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

console.log(gonzales.firstname); // Johny
不能将原型设置为函数本身(除非它是返回对象的自执行函数)函数虽然被认为是对象,但它们是不同的野兽,有着自己的魔力——不要像对象一样对待它们,因为它们不会善待它。不要尝试这样做,因为它会破坏一些Javascript继承,并会创建无数无法消除的bug


有关详细信息和准确命名,请参阅本文:

函数的问题在于它们确实具有不可写属性。这种不可写性甚至会影响从函数继承的对象,在您的例子中是
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”
三次

您可以使用使
.name=
失败的情况更加明显:

var Student = function(name){
    "use strict";
    this.name = name;
};
Student.prototype = function ProtoName() {};
new Student("test");
您将得到一个
错误:在严格模式下分配无效


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

原型不是函数,它是可以包含函数的对象!使用
Student.prototype={print:function(){print('Inside!');}}
或其他东西。但是,function也是一个对象,对吗?意义不同。是的,在JS中,函数“是”一个对象,但它本身不能是原型。我会发布一些东西,给我一个mo。@something这里:当然它可以是一个原型——每个对象都可以。OP演示了如何成功地使用它。@Bergi是的,它可以,但它肯定不会对任何人有任何好处。不过,值得一提的是,Student的每个实例现在都将共享该姓氏。我想知道的是,这个函数声明不是原型中的唯一函数,而是原型,所以这一定会破坏JS的内置系统。@something这里-你完全正确,我会更新我的帖子。谢谢你的回馈。