// Create a class of objects actually var Student = { name: "Robot" , height: 1.6 , RUN: function () { the console.log ( the this .name + 'Runing with' ); } } function createStudent (name) { / / based Student create a new object prototype of the Object.create () can be passed to an object, creating an object based on an object prototype chain var S = the Object.create (Student); // initialize the new object: s.name = name; return S; } var xiaoming=createStudent("小明"); xiaoming.run(); console.log(xiaoming.__proto__==Student);//true
The above is an example of a prototype chain to inherit
javascript create objects
JavaScript to set a prototype for each object will be created, pointing to its prototype object.
When we use obj.xxx
when property access an object, JavaScript engine first looks at the current object of the property, if not found, to find its prototype object, if it is not found, it has been traced back to the Object.prototype
subject, and finally, if you have not found , can only return undefined
.
For example, create a Array
target:
was arr = [1, 2, 3];
The prototype chain is:
arr ----> Array.prototype ----> Object.prototype ----> null
Array.prototype
It defined indexOf()
, shift()
and so on, so you can all Array
call these methods directly on the object.
When we create a function:
function foo() { return 0; }
Function is an object, its prototype chain is:
foo ----> Function.prototype ----> Object.prototype ----> null
Since the Function.prototype
definition of apply()
methods, therefore, all functions can be invoked apply()
method.
Easy to think, if the prototype chain is very long, then access an object's properties will spend more time looking for since become slower, so be careful not to do a prototype chain is too long.
Constructor
In addition to directly { ... }
create an object outside, JavaScript can also use a method of constructing function to create the object. Its use is to first define a constructor:
function Student(name) { this.name = name; this.hello = function () { alert('Hello, ' + this.name + '!'); } }
You may ask, Hey, this is not a normal function?
This is indeed a common function, but in JavaScript, you can use the keyword new
to call this function, and returns an object:
Var Xiaoming = New Student ( 'Hsiao Ming' ); Xiaoming.Name; // 'Hsiao Ming' Xiaoming.Hello (); // Hello, Hsiao Ming!
Note that if you do not write new
, this is a normal function, it returns undefined
. However, if you write new
, it becomes a constructor, which is bound this
objects point to the newly created, and return to the default this
, that is to say, do not need to write in the final return this;
.
The newly created xiaoming
prototype chain are:
xiaoming ----> Student.prototype ----> Object.prototype ----> null
In other words, xiaoming
the function prototype points to Student
the prototype. If you then created xiaohong
, xiaojun
then these objects and prototypes xiaoming
are the same:
xiaoming ↘ xiaohong -→ Student.prototype ----> Object.prototype ----> null xiaojun ↗
With the new Student()
object created also obtained from a prototype constructor
property that refers to the function Student
itself:
xiaoming.constructor === Student.prototype.constructor; // true Student.prototype.constructor === Student; // true Object.getPrototypeOf(xiaoming) === Student.prototype; // true xiaoming instanceof Student; // true
Note that, constructed with the constructor of the object is no prototype property
Constructor has prototype property
Now we believe xiaoming
, xiaohong
these objects are "inherited" from Student
.
But there is a small problem, to observe:
xiaoming.name; // '小明' xiaohong.name; // '小红' xiaoming.hello; // function: Student.hello() xiaohong.hello; // function: Student.hello() xiaoming.hello === xiaohong.hello; // false
xiaoming
And xiaohong
each name
different, this is right, otherwise we can not distinguish who is who.
xiaoming
And xiaohong
each of hello
a function, but they are two different functions, although the function name and the code are the same!
If we pass new Student()
to create a lot of objects that the hello
function is actually only need to share the same function on it, it saves a lot of memory.
Let's create a shared target hello
function, according to the search principle properties of the object, we just put hello
a function to move xiaoming
, xiaohong
these objects together on a prototype on it, that is Student.prototype
:
Modify the code as follows:
function Student (name) { the this .name = name; } Student.prototype.hello = function () { // This is to save memory Alert ( 'the Hello,' + the this .name + '!' ); };
With the new
creation of prototype-based JavaScript objects it is that simple!
Forget how to do write new
If a function is defined as a constructor for creating an object, but forget when you call write new
how to do?
In strict mode, this.name = name
the error, because this
the binding is undefined
in the non-strict mode, this.name = name
not an error, because this
the binding is window
, so inadvertently created a global variable name
and returns undefined
, the result is worse.
So, call the constructor do not forget to write new
. In order to distinguish between normal functions and constructors, by convention, the constructor first letter should be capitalized, but the first letter should be lowercase normal function, so that some of the grammar checker as jslint will be able to help you write a leak is detected new
.
Finally, we can write a createStudent()
function, inside the package all of the new
operations. A common programming model like this:
function Student (The props) { the this .name = props.name || 'Anonymous'; // default value 'Anonymous' the this .grade = || props.grade. 1; // default value. 1 } Student.prototype.hello = function () { Alert ( 'the Hello,' + the this .name + '!' ); }; function createStudent (The props) { return new new Student (The props || {}) }
This createStudent()
function has several great advantages: First, do not need new
to call, the second parameter is very flexible and can not pass, so you can also pass:
var xiaoming = createStudent({ name: '小明' }); xiaoming.grade; // 1
If the object is created, there are many attributes, we just need to pass some of the properties required, the rest of the property can use the default value. Since the argument is an Object, we do not need to remember the order of the parameters. If you happen from JSON
to get an object, you can create direct xiaoming
.