javascript原型_您需要了解的所有知识才能了解JavaScript的原型

javascript原型

by Shirshendu Bhowmick

通过Shirshendu Bhowmick

Most of the time, JavaScript’s prototype confuses people who have just started to learn JavaScript — especially if they’re from a C++ or Java background.

大多数时候,JavaScript的原型会使刚开始学习JavaScript的人感到困惑,特别是如果他们来自C ++或Java背景。

In JavaScript, inheritance works a bit differently compared to C++ or Java. JavaScript inheritance is more widely known as “prototypical inheritance”.

在JavaScript中,继承的作用与C ++或Java有所不同。 JavaScript继承被广泛称为“原型继承”。

Things become more difficult to understand when you also encounter class in JavaScript. The new class syntax looks similar to C++ or Java, but in reality, it works differently.

当您还遇到JavaScript class时,事情变得更加难以理解。 新的class语法看起来类似于C ++或Java,但实际上,它的工作方式有所不同。

In this article, we will try to understand “prototypal inheritance” in JavaScript. We also look into the new class based syntax and try to understand what it actually is. So let’s get started.

在本文中,我们将尝试理解JavaScript中的“原型继承”。 我们还将研究新的基于class的语法,并尝试了解其实际含义。 因此,让我们开始吧。

First, we will start with the old school JavaScript function and prototype.

首先,我们将从老式JavaScript函数和原型开始。

了解原型的需求 (Understanding the need for prototype)

If you have ever worked with JavaScript arrays or objects or strings, you have noticed that there are a couple of methods that are available by default.

如果您曾经使用过JavaScript数组,对象或字符串,那么您会注意到默认情况下有两种方法可用。

For example:

例如:

var arr = [1,2,3,4];arr.reverse(); // returns [4,3,2,1]
var obj = {id: 1, value: "Some value"};obj.hasOwnProperty('id'); // returns true
var str = "Hello World";str.indexOf('W'); // returns 6

Have you ever wondered where these methods come from? You haven’t defined these methods on your own.

您是否想知道这些方法从何而来? 您尚未自行定义这些方法。

Can you define your own methods like this? You could say that you can in this way:

您可以定义自己的方法吗? 您可以说可以这样:

var arr = [1,2,3,4];arr.test = function() {    return 'Hi';}arr.test(); // will return 'Hi'

This will work, but only for this variable called arr. Let’s say we have another variable called arr2 then arr2.test() will throw an error “TypeError: arr2.test is not a function”.

这将起作用,但仅适用于名为arr变量。 假设我们有另一个名为arr2变量,则arr2.test()将引发错误“ TypeError:arr2.test不是函数”。

So how do those methods become available to each and every instance of array / string / object? Can you create your own methods with the same behavior? The answer is yes. You need to do it in the right way. To help with this, in comes JavaScript’s prototype.

那么,这些方法如何可用于数组/字符串/对象的每个实例? 您可以创建具有相同行为的自己的方法吗? 答案是肯定的。 您需要以正确的方式进行操作。 为了解决这个问题,JavaScript的原型出现了。

Let’s first see where these functions are coming from. Consider the code snippet below:

首先让我们看看这些功能的来源。 考虑下面的代码片段:

var arr1 = [1,2,3,4];var arr2 = Array(1,2,3,4);

We have created two arrays in two different ways: arr1 with array literals and arr2 with Array constructor function. Both are equivalent to each other with some differences that don’t matter for this article.

我们以两种不同的方式创建了两个数组:带有数组文字的arr1和带有Array构造函数的arr2 。 两者彼此等效,但有一些区别对本文无关紧要。

Now coming to the constructor function Array — it is a predefined constructor function in JavaScript. If you open Chrome Developer tools and go to the console and type console.log(Array.prototype) and hit enter you will see something like below:

现在来看构造函数Array —它是JavaScript中预定义的构造函数。 如果您打开Chrome Developer工具并转到控制台,然后键入console.log(Array.prototype)并按enter您将看到类似以下内容:

There you will see all the methods that we were wondering about. So now we get from where those functions are coming. Feel free to try with String.prototype and Object.prototype.

在那里,您将看到我们想知道的所有方法。 因此,现在我们从这些功能的来源中获取信息。 随意尝试使用String.prototypeObject.prototype

Let’s create our own simple constructor function:

让我们创建自己的简单构造函数:

var foo = function(name) { this.myName = name; this.tellMyName = function() {   console.log(this.myName); }}
var fooObj1 = new foo('James');fooObj1.tellMyName(); // will print Jamesvar fooObj2 = new foo('Mike');fooObj2.tellMyName(); // will print Mike

Can you identify a fundamental problem with the above code? The problem is we are wasting memory with the above approach. Note that the method tellMyName is the same for each and every instance of foo. Each time we create an instance of foo the method tellMyName ends up taking space in the system’s memory. If tellMyName is the same for all the instances it’s better to keep it in a single place and make all our instances refer from that place. Let’s see how to do this.

您能确定上述代码的根本问题吗? 问题是我们在浪费上述方法的内存。 请注意,方法foo每个实例的tellMyName都是相同的。 每次我们创建foo实例时, tellMyName方法最终都会占用系统内存。 如果tellMyName对于所有实例都是相同的,则最好将其放在单个位置,并使我们的所有实例都从该位置引用。 让我们看看如何做到这一点。

var foo = function(name) { this.myName = name;}
foo.prototype.tellMyName = function() {   console.log(this.myName);}
var fooObj1 = new foo('James');fooObj1.tellMyName(); // will print Jamesvar fooObj2 = new foo('Mike');fooObj2.tellMyName(); // will print Mike

Let’s check the difference with the above approach and previous approach. With the above approach, if you console.dir() the instances then you will see something like this:

让我们检查一下上述方法和先前方法的区别。 使用上述方法,如果您使用console.dir()实例,则将看到类似以下内容:

Note that as a property of the instances we only have myname. tellMyName is defined under __proto__. I will come to this __proto__ after sometime. Most importantly note that comparing tellMyName of both the instances evaluates to true. Function comparison in JavaScript evaluates true only if their references are the same. This proves that tellMyName is not consuming extra memory for multiple instances.

请注意,作为实例的属性,我们只有mynametellMyName__proto__下定义。 一段时间后,我会__proto__这个__proto__ 。 最重要的是,比较两个实例的tellMyName的结果为true。 仅当它们的引用相同时,JavaScript中的函数比较才会评估为true。 这证明tellMyName不会为多个实例消耗额外的内存。

Let’s see the same thing with the previous approach:

让我们看一下与前面的方法相同的东西:

Note that this time tellMyName is defined as a property of the instances. It’s no longer under that __proto__. Also, note that this time comparing the functions evaluates to false. This is because they are at two different memory locations and their references are different.

请注意,这次tellMyName被定义为实例的属性。 不再在那个__proto__ 。 另外,请注意,这次比较函数的结果为false。 这是因为它们位于两个不同的内存位置,并且它们的引用也不同。

I hope by now you understand the necessity of prototype.

我希望现在您了解了prototype的必要性。

Now let’s look into some more detail about prototype.

现在让我们研究有关原型的更多细节。

Each and every JavaScript function will have a prototype property which is of the object type. You can define your own properties under prototype. When you will use the function as a constructor function, all the instances of it will inherit properties from the prototype object.

每个JavaScript函数都将具有对象类型的prototype属性。 您可以在prototype下定义自己的属性。 当您将函数用作构造函数时,它的所有实例都将从prototype对象继承属性。

Now let’s come to that __proto__ property you saw above. The __proto__ is simply a reference to the prototype object from which the instance has inherited. Sounds complicated? It’s actually not that complicated. Let’s visualize this with an example.

现在,让我们来看一下您在上面看到的__proto__属性。 __proto__只是对实例所继承的原型对象的引用。 听起来复杂吗? 实际上并不那么复杂。 让我们用一个例子来形象化。

Consider the code below. We already know creating an Array with array literals will inherit properties from Array.prototype.

考虑下面的代码。 我们已经知道使用数组文字创建Array将继承Array.prototype属性。

var arr = [1, 2, 3, 4];

What I just said above is “The __proto__ is simply a reference to the prototype object from which the instance has inherited”. So arr.__proto__ should be the same with Array.prototype. Let’s verify this.

我上面所说的是“ __proto__只是对实例继承自其的原型对象的引用 ”。 因此arr.__proto__应该与Array.prototype相同。 让我们验证一下。

Now we shouldn’t access the prototype object with __proto__. According to MDN using __proto__ is highly discouraged and may not be supported in all browsers. The correct way of doing this:

现在我们不应该使用__proto__访问原型对象。 根据MDN的建议,强烈建议不要使用__proto__ ,并非所有浏览器都支持。 正确的方法是:

var arr = [1, 2, 3, 4];var prototypeOfArr = Object.getPrototypeOf(arr);prototypeOfArr === Array.prototype;prototypeOfArr === arr.__proto__;

The last line of the above code snippet shows that __proto__ and Object.getPrototypeOf return the same thing.

上面的代码片段的最后一行显示__proto__Object.getPrototypeOf返回相同的东西。

Now it’s time for a break. Grab a coffee or whatever you like and try out the examples above on your own. Once you are ready, come back to this article and we will then continue.

现在该休息一下了。 拿起咖啡或您喜欢的任何东西,然后自己尝试上面的示例。 准备就绪后,请返回本文,然后我们将继续。

原型链与继承 (Prototype chaining & Inheritance)

In Fig: 2 above, did you notice that there is another __proto__ inside the first __proto__ object? If not then scroll up a bit to Fig: 2. Have a look and come back here. We will now discuss what that is actually. That is known as prototype chaining.

在上面的图2中,您是否注意到第一个__proto__对象内还有另一个__proto__ ? 如果没有,请向上滚动至图:2.看一看,然后回到这里。 现在,我们将讨论实际上是什么。 这就是所谓的原型链。

In JavaScript, we achieve Inheritance with the help of prototype chaining.

在JavaScript中,我们借助原型链实现了继承。

Consider this example: We all understand the term “Vehicle”. A bus could be called as a vehicle. A car could be called a vehicle. A motorbike could be called a vehicle. Bus, car, and motorbike have some common properties that's why they are called vehicle. For example, they can move from one place to another. They have wheels. They have horns, etc.

考虑以下示例:我们都理解术语“车辆”。 公共汽车可以称为车辆。 汽车可以称为车辆。 摩托车可以称为车辆。 公共汽车,汽车和摩托车具有一些共同的属性,因此被称为车辆。 例如,它们可以从一个地方移动到另一个地方。 他们有轮子。 他们有角等

Again bus, car, and motorbike can be of different types for example Mercedes, BMW, Honda, etc.

同样,公共汽车,汽车和摩托车可以是不同的类型,例如梅赛德斯,宝马,本田等。

In the above illustration, Bus inherits some property from vehicle, and Mercedes Benz Bus inherits some property from bus. Similar is the case for Car and MotorBike.

在上图中,Bus从车辆继承了一些属性,而Mercedes Benz Bus从bus继承了一些属性。 汽车和摩托车也是如此。

Let's establish this relationship in JavaScript.

让我们在JavaScript中建立这种关系。

First, let's assume a few points for the sake of simplicity:

首先,为简单起见,我们假设以下几点:

  1. All buses have 6 wheels

    所有巴士有6个轮子
  2. Accelerating and Braking procedures are different across buses, cars, and motorbikes, but the same across all buses, all cars, and all motorbikes.

    公交车,汽车和摩托车的加速和制动程序不同,但所有公交车,所有汽车和所有摩托车的加速和制动程序均相同。
  3. All vehicles can blow the horn.

    所有车辆都可以吹喇叭。
function Vehicle(vehicleType) {  //Vehicle Constructor    this.vehicleType = vehicleType;}
Vehicle.prototype.blowHorn = function () {    console.log('Honk! Honk! Honk!'); // All Vehicle can blow Horn}
function Bus(make) { // Bus Constructor  Vehicle.call(this, "Bus");      this.make = make}
Bus.prototype = Object.create(Vehicle.prototype); // Make Bus constructor inherit properties from Vehicle Prototype Object
Bus.prototype.noOfWheels = 6; // Let's assume all buses have 6 wheels
Bus.prototype.accelerator = function() {    console.log('Accelerating Bus'); //Bus accelerator}
Bus.prototype.brake = function() {    console.log('Braking Bus'); // Bus brake}
function Car(make) {  Vehicle.call(this, "Car");  this.make = make;}
Car.prototype = Object.create(Vehicle.prototype);
Car.prototype.noOfWheels = 4;
Car.prototype.accelerator = function() {    console.log('Accelerating Car');}
Car.prototype.brake = function() {    console.log('Braking Car');}
function MotorBike(make) {  Vehicle.call(this, "MotorBike");  this.make = make;}
MotorBike.prototype = Object.create(Vehicle.prototype);
MotorBike.prototype.noOfWheels = 2;
MotorBike.prototype.accelerator = function() {    console.log('Accelerating MotorBike');}
MotorBike.prototype.brake = function() {    console.log('Braking MotorBike');}
var myBus = new Bus('Mercedes');var myCar = new Car('BMW');var myMotorBike = new MotorBike('Honda');

Allow me to explain the above code snippet.

请允许我解释上面的代码片段。

We have a Vehicle constructor which expects a vehicle type. As all vehicles can blow their horns, we have a blowHorn property in Vehicle's prototype.

我们有一个Vehicle构造函数,它期望车辆类型。 由于所有车辆都可以blowHorn ,因此我们在Vehicle的原型中拥有一个blowHorn属性。

As Bus is a vehicle it will inherit properties from Vehicle object.

由于Bus是车辆,它将从Vehicle对象继承属性。

We have assumed all buses will have 6 wheels and have the same accelerating and braking procedures. So we have noOfWheels, accelerator and brake property defined in Bus’s prototype.

我们假设所有公交车将有6个车轮,并且具有相同的加速和制动程序。 因此,我们在Bus的原型中定义了noOfWheelsacceleratorbrake属性。

Similar logic applies for Car and MotorBike.

类似的逻辑适用于Car和MotorBike。

Let’s go to Chrome Developer Tools -> Console and execute our code.

让我们转到Chrome开发者工具->控制台并执行我们的代码。

After execution, we will have 3 objects myBus, myCar, and myMotorBike.

执行后,我们将有3个对象myBusmyCarmyMotorBike

Type console.dir(mybus) in the console and hit enter. Use the triangle icon to expand it and you will see something like below:

在控制台中键入console.dir(mybus) ,然后按enter 。 使用三角形图标将其展开,您将看到类似以下的内容:

Under myBus we have properties make and vehicleType. Notice the value of __proto__ is prototype of Bus. All the properties of its prototype are available here: accelerator, brake, noOfWheels.

myBus我们具有属性makevehicleType 。 注意__proto__的值是Bus原型。 它的原型的所有属性都可以在此处使用: acceleratorbrakenoOfWheels

Now have a look that the first __proto__ object. This object has another __proto__ object as its property.

现在看看第一个__proto__对象。 该对象具有另一个__proto__对象作为其属性。

Under which we have blowHorn and constructor property.

在此之下,我们具有blowHornconstructor属性。

Bus.prototype = Object.create(Vehicle.prototype);

Remember the line above? Object.create(Vehicle.prototype) will create an empty object whose prototype is Vehicle.prototype. We set this object as a prototype of Bus. For Vehicle.prototype we haven’t specified any prototype so by default it inherits from Object.prototype.

还记得上面的那一行吗? Object.create(Vehicle.prototype)将创建一个原型为Vehicle.prototype的空对象。 我们将此对象设置为Bus的原型。 对于Vehicle.prototype我们没有指定任何原型,因此默认情况下它继承自Object.prototype

Let’s see the magic below:

让我们来看看下面的魔术:

We can access the make property as it is myBus's own property.

我们可以访问make属性,因为它是myBus的财产。

We can access the brake property from myBus's prototype.

我们可以从myBus的原型访问brake属性。

We can access the blowHorn property from myBus's prototype’s prototype.

我们可以从myBus的原型的原型中访问blowHorn属性。

We can access the hasOwnProperty property from myBus's prototype’s prototype’s prototype. :)

我们可以从myBus的原型的原型的原型访问hasOwnProperty属性。 :)

This is called prototype chaining. Whenever you access a property of an object in JavaScript, it first checks if the property is available inside the object. If not it checks its prototype object. If it is there then good, you get the value of the property. Otherwise, it will check if the property exists in the prototype’s prototype, if not then again in the prototype’s prototype’s prototype and so on.

这称为原型链。 每当您在JavaScript中访问对象的属性时,它都会首先检查该属性在对象内部是否可用。 如果不是,它将检查其原型对象。 如果在那里,那么好,您将获得属性的值。 否则,它将检查属性是否存在于原型的原型中,如果不存在,则再次在原型的原型的原型中存在,依此类推。

So how long it will check in this manner? It will stop if the property is found at any point or if the value of __proto__ at any point is null or undefined. Then it will throw an error to notify you that it was unable to find the property you were looking for.

那么它将以这种方式检查多长时间? 如果在任何时候找到该属性,或者在任何时候__proto__的值为nullundefined ,它将停止。 然后,它将引发错误,通知您找不到所需的属性。

This is how inheritance works in JavaScript with the help of prototype chaining.

这就是在原型链的帮助下继承在JavaScript中的工作方式。

Feel free to try the above example with myCar and myMotorBike.

随意使用myCarmyMotorBike尝试上述示例。

As we know, in JavaScript everything is an object. You will find that for every instance, the prototype chain ends with Object.prototype.

众所周知,在JavaScript中,一切都是对象。 您会发现,对于每个实例,原型链都以Object.prototype

The exception for the above rule is if you create an object with Object.create(null)

上述规则的例外是如果您使用Object.create(null)创建对象

var obj = Object.create(null)

With the above code obj will be an empty object without any prototype.

使用上面的代码, obj将是一个没有任何原型的空对象。

For more information on Object.create check out the documentation on MDN.

有关Object.create更多信息,请查看MDN上的文档。

Can you change the prototype object of an existing object? Yes, with Object.setPrototypeOf() you can. Check out the documentation in MDN.

您可以更改现有对象的原型对象吗? 是的,可以使用Object.setPrototypeOf() 。 查看MDN中的文档。

Want to check if a property is the object’s own property? You already know how to do this.Object.hasOwnProperty will tell you if the property is coming from the object itself or from its prototype chain. Check out its documentation on MDN.

是否想检查一个属性是否是该对象自己的属性? 您已经知道如何执行此操作。 Object.hasOwnProperty将告诉您该属性是来自对象本身还是来自其原型链。 查看其有关MDN的文档。

Note that __proto__ also referred to as [[Prototype]].

请注意, __proto__也称为[[Prototype]]

Now it’s time for another break. Once you are ready, come back to this article. We will then continue and I promise this is the last part.

现在该休息一下了。 准备就绪后,请返回本文。 然后我们将继续,我保证这是最后一部分。

了解JavaScript中的类 (Understanding Classes in JavaScript)

According to MDN:

根据MDN:

JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript’s existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript.

ECMAScript 2015中引入JavaScript类主要是对JavaScript现有的基于原型的继承的语法糖。 类语法不会向JavaScript引入新的面向对象的继承模型。

Classes in JavaScript will provide better syntax to achieve what we did above in a much cleaner way. Let’s have a look into the class syntax first.

JavaScript中的类将提供更好的语法,以一种更简洁的方式实现我们上面的工作。 首先让我们看一下类语法。

class Myclass {  constructor(name) {    this.name = name;  }    tellMyName() {    console.log(this.name)  }}
const myObj = new Myclass("John");

constructor method is a special type of method. It will be automatically executed whenever you create an instance of this class. Inside your class body. Only one occurrence of constructor is possible.

constructor方法是一种特殊的方法。 每当您创建此类的实例时,它将自动执行。 在班级内部。 constructor只能出现一次。

The methods that you will define inside the class body will be moved to the prototype object.

您将在类主体中定义的方法将移至原型对象。

If you want some property inside the instance you can define it in the constructor, as we did with this.name = name.

如果要在实例中包含某些属性,则可以在构造函数中定义它,就像我们对this.name = name所做的那样。

Let’s have a look into our myObj.

让我们看一下myObj

Note that we have the name property inside the instance that is myObj and the method tellMyName is in the prototype.

请注意,我们在实例内部具有name属性,即myObj并且原型中包含方法tellMyName

Consider the code snippet below:

考虑下面的代码片段:

class Myclass {  constructor(firstName) {    this.name = firstName;  }    tellMyName() {    console.log(this.name)  }  lastName = "lewis";}
const myObj = new Myclass("John");

Let’s see the output:

让我们看一下输出:

See that lastName is moved into the instance instead of prototype. Only methods you that you declare inside the Class body will be moved to prototype. There is an exception though.

看到lastName被移入实例而不是原型。 只有您在类主体中声明的方法才会移至原型。 但是有一个例外。

Consider the code snippet below:

考虑下面的代码片段:

class Myclass {  constructor(firstName) {    this.name = firstName;  }    tellMyName = () => {    console.log(this.name)  }  lastName = "lewis";}
const myObj = new Myclass("John");

Output:

输出:

Note that tellMyName is now an arrow function, and it has been moved to the instance instead of prototype. So remember that arrow functions will always be moved to the instance, so use them carefully.

请注意, tellMyName现在是一个箭头函数,并且已移至实例而不是原型。 因此请记住,箭头功能将始终移至实例,因此请谨慎使用它们。

Let’s look into static class properties:

让我们看一下静态类的属性:

class Myclass {  static welcome() {    console.log("Hello World");  }}
Myclass.welcome();const myObj = new Myclass();myObj.welcome();

Output:

输出:

Static properties are something that you can access without creating an instance of the class. On the other hand, the instance will not have access to the static properties of a class.

您可以在不创建类实例的情况下访问静态属性。 另一方面,实例将无法访问类的静态属性。

So is static property a new concept that is available only with the class and not in the old school JavaScript? No, it’s there in old school JavaScript also. The old school method of achieving static property is:

那么,静态属性是仅在类中可用而不在旧式JavaScript中可用的新概念吗? 不,它在老式JavaScript中也存在。 实现静态属性的传统方法是:

function Myclass() {}Myclass.welcome = function() {  console.log("Hello World");}

Now let’s have a look at how we can achieve inheritance with classes.

现在让我们看一下如何实现类的继承。

class Vehicle {  constructor(type) {    this.vehicleType= type;  }  blowHorn() {    console.log("Honk! Honk! Honk!");  }}
class Bus extends Vehicle {  constructor(make) {    super("Bus");    this.make = make;   }  accelerator() {    console.log('Accelerating Bus');  }  brake() {    console.log('Braking Bus');  }}
Bus.prototype.noOfWheels = 6;
const myBus = new Bus("Mercedes");

We inherit other classes using the extends keyword.

我们使用extends关键字继承其他类。

super() will simply execute the parent class’s constructor. If you are inheriting from other classes and you use the constructor in your child class, then you have to call super() inside the constructor of your child class otherwise it will throw an error.

super()将仅执行父类的构造函数。 如果要从其他类继承,并且在子类中使用构造函数,则必须在子类的构造函数内部调用super() ,否则将引发错误。

We already know that if we define any property other than a normal function in the class body it will be moved to the instance instead of prototype. So we define noOfWheel on Bus.prototype.

我们已经知道,如果在类主体中定义除普通函数以外的任何属性,它将被移至实例而不是原型。 因此,我们在noOfWheel上定义了Bus.prototype

Inside your class body if you want to execute parent class’s method you can do that using super.parentClassMethod().

如果您要执行父类的方法,则可以在类主体内使用super.parentClassMethod()

Output:

输出:

The above output looks similar to our previous function based approach in Fig: 7.

上面的输出类似于图7中我们先前基于函数的方法。

结语 (Wrapping up)

So should you use new class syntax or old constructor based syntax? I guess there is no definite answer to this question. It depends on your use case.

那么,您应该使用新的类语法还是旧的基于构造函数的语法? 我想这个问题没有确切的答案。 这取决于您的用例。

In this article, for the classes part I have just demonstrated how you can achieve prototypical inheritance classes. There is more to know about JavaScript classes, but that’s out of the scope of this article. Check out the documentation of classes on MDN. Or I will try to write an entire article on classes at some time.

在本文中,对于类,我刚刚演示了如何实现原型继承类。 关于JavaScript类,还有更多的知识,但这超出了本文的范围。 查看MDN上的类的文档。 或者,我有时会尝试撰写有关课程的整篇文章。

If this article helped you in understanding prototypes, I would appreciate if you could applaud a little.

如果本文能帮助您理解原型,不胜感激,我将不胜感激。

If you want me to write on some other topic, let me know in the responses.

如果您想让我写其他话题,请在回复中告诉我。

You can also connect with me over LinkedIn.

您也可以通过LinkedIn与我联系。

谢谢您的阅读。 :) (Thank You for Reading. :))

翻译自: https://www.freecodecamp.org/news/all-you-need-to-know-to-understand-javascripts-prototype-a2bff2d28f03/

javascript原型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值