new
operator, a new object is created. function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } var p1 = new Person('John', 'Doe'); var p2 = new Person('Robert', 'Doe');
p1
and p2
two different objects, each of which is created using the Person
constructor. As you can see from the following example, they are independent instances of Person
: console.log(p1 instanceof Person); // 'true' console.log(p2 instanceof Person); // 'true' console.log(p1 === p2); // 'false'
prototype
.prototype
, which is an object, is inherited from the parent prototype again and again until it reaches the top level. This is often called a prototype chain . At the beginning of the chain is always the Object.prototype
(that is, at the topmost level of the prototype chain); it contains the toString()
, hasProperty()
, isPrototypeOf()
methods, and so on.new
operator), it inherits all the properties through the prototype. However, keep in mind that instances do not have direct access to the prototype object, only its properties. // Person // 'getFullName': Person.prototype.getFullName = function() { return this.firstName + ' ' + this.lastName; } // p1 console.log(p1.getFullName()); // 'John Doe' // p1 'prototype'... console.log(p1.prototype); // 'undefined' console.log(p1.prototype.getFullName()); //
p1
was created before defining the getFullName
method, it will still have access to it, because its prototype was the prototype of Person
.__proto__
property, but its use spoils karma, at least because it is not in ECMAScript standard , so do not use it ).Person
p1
instance does not have direct access to the prototype object, we must rewrite the getFullName
method in p1
like this: // p1.getFullName, ** p1.prototype.getFullName, // p1.prototype : p1.getFullName = function(){ return ' '; }
p1
has its own property getFullName
. But the p2
instance does not have its own implementation of this property. Accordingly, the call to p1.getFullName
pulls the object's own method of p1
, while the call to p2.getFullName()
goes up the prototype chain to Person
. console.log(p1.getFullName()); // ' ' console.log(p2.getFullName()); // 'Robert Doe'
function Parent() { this.someVar = 'someValue'; }; // Parent, 'sayHello' Parent.prototype.sayHello = function(){ console.log('Hello'); }; function Child(){ // // . Parent.call(this); }; // Child 'otherVar'... Child.prototype.otherVar = 'otherValue'; // ... Child Parent // ( 'otherVar', // Child 'otherVar' ) Child.prototype = Object.create(Parent.prototype); var child = new Child(); child.sayHello(); // 'Hello' console.log(child.someVar); // 'someValue' console.log(child.otherVar); // 'undefined'
hasOwnProperty
method, hasOwnProperty
can verify that this is the object's own property). // var message = 'Hello World'; var sayHello = function(n){ // 1 var i = 0; var innerSayHello = function() { // 2 console.log((i + 1) + ': ' + message); // 2 } for (i = 0; i < n; i++) { innerSayHello(); } // 1 }; sayHello(3); // : // 1: Hello World // 2: Hello World // 3: Hello World
this
and arguments
).window
object, and that the global object contains other objects, such as console
and location
.ReferenceError
.try-catch
or with
blocks are encountered. In all these cases, a new object is created and placed at the top of the visibility chain. function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }; function persist(person) { with (person) { // 'person' // "with", // 'firstName' 'lastName', person.firstName // person.lastName if (!firstName) { throw new Error('FirstName is mandatory'); } if (!lastName) { throw new Error('LastName is mandatory'); } } try { person.save(); } catch(error) { // , 'error' console.log('Impossible to store ' + person + ', Reason: ' + error); } } var p1 = new Person('John', 'Doe'); persist(p1);
for (var i = 0; i < 10; i++) { /* ... */ } // 'i' ! console.log(i); // '10'
i
will be limited to a for block. But not in javascript. i is added to the Activation Object at the top of the scope chain, and remains there until the object is deleted, which happens after the execution context is removed from the stack. This behavior is known as floating variables.let
keyword. It is already available in JavaScript 1.7 and should become an officially supported keyword starting with ECMAScript 6. var start = new Date().getTime(); function Parent() { this.delta = 10; }; function ChildA(){}; ChildA.prototype = new Parent(); function ChildB(){} ChildB.prototype = new ChildA(); function ChildC(){} ChildC.prototype = new ChildB(); function ChildD(){}; ChildD.prototype = new ChildC(); function ChildE(){}; ChildE.prototype = new ChildD(); function nestedFn() { var child = new ChildE(); var counter = 0; for(var i = 0; i < 1000; i++) { for(var j = 0; j < 1000; j++) { for(var k = 0; k < 1000; k++) { counter += child.delta; } } } console.log('Final result: ' + counter); } nestedFn(); var end = new Date().getTime(); var diff = end - start; console.log('Total time: ' + diff + ' milliseconds');
delta
. But the delta value is determined at the very top of the inheritance tree! This means that each time you call child.delta
entire tree is viewed from top to bottom . This can adversely affect performance.child.delta
value of child.delta
in the delta
variable: function nestedFn() { var child = new ChildE(); var counter = 0; var delta = child.delta; // cache child.delta value in current scope for(var i = 0; i < 1000; i++) { for(var j = 0; j < 1000; j++) { for(var k = 0; k < 1000; k++) { counter += delta; // no inheritance tree traversal needed! } } } console.log('Final result: ' + counter); } nestedFn(); var end = new Date().getTime(); var diff = end - start; console.log('Total time: ' + diff + ' milliseconds');
child.delta
will not change during the execution of loops; otherwise, we will have to periodically update the value of the variable with the current value.nestedFn
and see if there is a noticeable difference in performance between them. diego@alkadia:~$ node test.js Final result: 10000000000 Total time: 8270 milliseconds
diego@alkadia:~$ node test2.js Final result: 10000000000 Total time: 1143 milliseconds
// DOM $('.container') "n" for (var i = 0; i < n; i++) { $('.container').append(“Line “+i+”<br />”); } // ... // , $('.container') , // DOM "n" var $container = $('.container'); for (var i = 0; i < n; i++) { $container.append("Line "+i+"<br />"); } // ... // DOM $('.container') , // DOM var $html = ''; for (var i = 0; i < n; i++) { $html += 'Line ' + i + '<br />'; } $('.container').append($html);
Source: https://habr.com/ru/post/223027/
All Articles