构造函数-原型- __proto__

constructor - prototype - __proto__

本文关键字:proto 原型 构造函数      更新时间:2023-09-26

我正在学习javascript,很难理解下面解释的第二部分。你们当中有谁能给我讲讲这件事吗?

"构造函数的实际原型是函数。原型,因为构造函数是函数。它的prototype属性将是通过它创建的实例的prototype,但不是它自己的prototype"

我想做一系列的比较会帮助你弄清楚的。

构造函数的实际原型是function。原型,因为构造函数是函数

function IamAConstructorFunc() {} // A constructor function
IamAConstructorFunc.constructor // function Function()
IamAConstructorFunc.constructor.prototype // function Empty()
IamAConstructorFunc.constructor.prototype === Function.prototype // True
IamAConstructorFunc.constructor.prototype === Object.prototy // False

它的prototype属性将是通过它创建的实例的原型

var IObj = new IamAConstructorFunc; // Instance of IamAConstructorFunc
IObj.__proto__ === IamAConstructorFunc.prototype // True
IObj.constructor === IamAConstructorFunc // True
IObj instanceof IamAConstructorFunc // True

但不是它自己的原型

IamAConstructorFunc有一个prototype,但它不是它自己的原型,它是Object的一个实例,这个实例原型是:

IamAConstructorFunc.prototype.__proto__ === Object.prototype // True

好的,这里有一个例子:

function Widget() {
   console.log('Widget constructor invoked');
}

Function.prototype.sayHi = function() { console.log('Function prototype.sayHi invoked'); };
Widget.prototype.sayHi = function() { console.log('Widget prototype.sayHi invoked') };
var w = new Widget();
console.log('Calling w.sayHi()');
w.sayHi();    
console.log('Calling Widget.sayHi()');
Widget.sayHi(); 

这将产生以下日志输出:

部件构造函数被调用

调用w.sayHi ()

部件原型。sayHi调用

调用Widget.sayHi ()

函数原型。sayHi调用

调用w.sayHi()是调用Widget对象上的方法,而调用Widget.sayHi()是调用函数上的方法。他们有两个不同的原型

这太复杂了。

函数可用于创建对象。

function MyFunc(a, b) {
    this.a = a;
    this.b = b;
}
var myObj = new MyFunc(a, b);

函数的原型可以用来创建在该对象上工作的函数。

MyFunc.prototype.sum = function() {
    return this.a + this.b;
}
var myObj = new MyFunc(2, 3);
var true = (myObj.sum() === (2 + 3));

查看示例可能更容易。

function Person(first, last) {
  this.first = first;
  this.last = last;
}
Person.prototype.fullName = function() {
   return this.first + " " + this.last; 
}
var fred = new Person("Fred", "Flintstone");
var barney = new Person("Barney", "Rubble");
var output = document.getElementById("output");
output.innerHTML += fred.fullName() + "<br>'n";
output.innerHTML += barney.fullName() + "<br>'n";
#output {
  color:blue;
  font-weight:bold;
}
<div id="output">
  
</div>

我认为问题是一个函数的prototype属性和内部原型之间的混淆,每个对象都有。

每个函数都有一个prototype属性。这个属性就像任何对象的其他属性一样。它唯一的特殊之处在于,它将被用作由该函数创建的任何对象的内部原型。

function A() {
}
//add property c to public prototype property of A
A.prototype.c = 1;
//create a new instance -> a will get A's prototype property as internal prototype
a = new A();
//a has therefore access to the property c, that was defined earlier
console.log(a.c); //1

因为函数在JavaScript中也是对象,所以它们也有一个内部原型。

function A() {}
//apply is part of A's prototype chain. 
//It's defined on its internal prototype objects,
//which was created by its own constructor, named "Function"
A.apply(this, []);

这句话几乎把我逼疯了,但我最终还是理解了它。实际上,在JavaScript中,构造函数在创建时被自动分配一个名为prototype的属性。

此属性将被通过此构造函数创建的所有实例用作自己的原型,并且无论如何都不会引用构造函数本身的实际原型。实际上,构造函数原型是Function.prototype.

var Cat = function() {};
Cat.__proto__ === Function.prototype; // true
var kitty = new Cat;
kitty.__proto__ === Cat.prototype; // true

这是正常的,因为Cat(我们的构造函数)本身就是一个函数,所以它派生自Function.prototype。kitty来自于Cat的新关键字call所以它来源于Cat.prototype.

那么在语句中:

构造函数的实际原型是function。原型,因为构造函数是函数。

实际原型引用构造函数(Cat)的__proto__属性。

它的prototype属性将是通过它创建的实例的prototype,但不是它自己的prototype。

它的原型属性是指.prototype