TDD test-driven javascript development (2) ------ learn prototype in javascript

Source: Internet
Author: User
1. in prototype mode 1.1, each function we create has a prototype attribute, which is a pointer pointing to an object, the purpose of this object is to include attributes and methods that can be shared by all instances of a specific type. A simple explanation of the above is: first, we... syntaxHighlighter. all (); 1. in prototype mode 1.1, each function we create has a prototype attribute, which is a pointer pointing to an object, the purpose of this object is to include attributes and methods that can be shared by all instances of a specific type. A simple explanation is as follows: first, we need to know the existence of classes in object-oriented languages, javascript is also an object-oriented language (this sentence may have some faults, but it does not affect). When defining a class function in javascript, by default, a prototype attribute is created. All attributes and methods in this prototype attribute are shared by all instances of this class. See the code: [javascript] // create a Person class function Person () {} // prototype of the Person class contains the name, age attribute and sayName () method Person. prototype. name = "defaultName"; Person. prototype. age = 29; Person. prototype. sayName = function () {return this. name ;}; var person = new Person (); var person3 = new Person (); TestCase ("test extends", {"test person. sayName () shocould be equals person3.sayName () ": function () {assertEquals (person. s AyName (), person3.sayName () ;}}); 1.2 by default, all prototype objects will automatically obtain a constructor (constructor) attribute, this attribute contains a pointer to the function of the prototype attribute. Person. prototype. constructor points to Person. When an attribute is added to an object instance, this attribute will shield the attributes of the same name stored in the prototype object (it will only prevent us from accessing the attribute in the prototype, but we can use the delete operator to delete instance attributes so that we can continue to access the attributes in the prototype and see the code: [javascript] // create a Person class function Person () {}// the Person class prototype contains the name, age attribute, and sayName () method Person. prototype. name = "defaultName"; Person. prototype. age = 29; Person. prototype. sayName = function () {alert (this. name) ;}; var person = new Person (); perso N. sayName (); // defaultName var person2 = new Person (); person2.name = "person2"; person2.sayName (); // person2 // delete the name attribute delete person2.name In the instance; person2.sayName (); // defaultName 1.3 Use the hasOwnProperty () method to detect whether an attribute exists in the instance or in the prototype, true [javascript] function Person () {} // Person class prototype is returned only when the specified property exists in the instance of the object. The prototype includes the name, age property, and sayName () method Person. prototype. name = "defaultName"; Person. prototype. age = 29; Person. prototype. sayName = function () {return this. name ;}; var person = new Person (); var person2 = new Person (); person2.name = "person2"; TestCase ("test extends ", {"test person shoshould not be hasOwnProperty name": function () {assertEquals (false, person. hasOwnProperty ("name") ;}, "test person2 shocould not be hasOwnProperty name": function () {assertEquals (true, person2.hasOwnProperty ("name ")); },}); 1.4 Use the in operator to determine whether an attribute is the in operator in the prototype. As long as the attribute can be accessed through the object, true is returned (hasOwnProperty () true is returned only when the attribute exists in the instance. Therefore, as long as the in operator returns true, hasOwnProperty () returns false, this property is proved to be an attribute in the prototype. See the Code: [javascript] // create a Person class function Person () {}// the Person class prototype contains the name, age attribute, and sayName () method Person. prototype. name = "defaultName"; Person. prototype. age = 29; Person. prototype. sayName = function () {alert (this. name) ;}; var person = new Person (); Var person2 = new Person (); person2.name = "person2"; person2.color = "blue"; TestCase ("test extends", {"test Person person Person. hasOwnProperty (name) ": function () {assertEquals (false, person. hasOwnProperty ("name"); // name is the property in the prototype and does not exist in the instance}, "test Person name in person": function () {assertEquals (true, "name" in person) ;}, "test Person person2.hasOwnProperty (name)": function () {assertEquals (true, pe Rson2.hasOwnProperty ("name"); // name is the property of the Instance Object}, "test Person Person2 name in person2": function () {assertEquals (true, "name" in person2) ;}, "test Person person2.hasOwnProperty (color)": function () {assertEquals (true, person2.hasOwnProperty ("color ")); // color is the property of the Instance Object}, "test Person color property in Person2": function () {assertEquals (true, "color" in person2 ); // color is the attribute of the instance object, and can also be accessed in}); 1. All the attributes of the five instances-Object. keys () [javascript] function Person () {}// prototype of the Person class contains the name, age attribute, and sayName () method Person. prototype. name = "defaultName"; Person. prototype. age = 29; Person. prototype. sayName = function () {return this. name ;}; var person = new Person (); var person2 = new Person (); person2.name = "person2"; var keys = Object. keys (Person. prototype); var keys2 = Object. keys (person2); TestC Ase ("test extends", {"test keys shocould be an array": function () {assertArray ("keys is not an array", keys );}, "test keys [0] shocould be equals name": function () {assertEquals ("name", keys [0]);}, "test keys [1] shocould be equals age": function () {assertEquals ("age", keys [1]);}, "test keys [2] shocould be equals age": function () {assertEquals ("sayName", keys [2]);}, "test keys2 shocould be an array ": Function () {assertArray ("keys is not an array", keys2) ;}, "test keys2 [0] shocould be equals age": function () {assertEquals ("name", keys2 [0]) ;}}); 1.6 simpler prototype syntax ----- literally create object [javascript] function Person () {} Person. prototype = {name: "defaultName", age: 20, sayName: function () {return this. name ;}}; when creating a function, we know that every time a function is created, its prototype object will be created at the same time, and this object will automatically obtain the constructor. The syntax (literally) we use here completely overwrites the default prototype object, therefore, the constructor Object becomes the constructor attribute of the new Object (pointing to the Object constructor) and does not point to the Person function. [Javascript] function Person () {} Person. prototype = {name: "defaultName", age: 20, sayName: function () {return this. name ;}}; var con = new Person (); TestCase ("test extends", {"test con shoshould be instance of Object": function () {assertInstanceOf ("con shoud be instance of Obejct", Object, con) ;}, "test con shocould be instance of Person": function () {assertInstanceOf ("con shoud be instanc E of Person ", Person, con) ;}," test con constructor shocould be equals Person ": function () {assertNotEquals (Person, con. constructor); // no longer equal to Person}, "test con constructor shocould not be equals Object": function () {assertEquals (Object, con. constructor) ;}, "test con constructor shoshould be same as Person": function () {assertNotSame (Person, con. constructor) ;}, "test con constructor shocould not be sa Me as Object ": function () {assertSame (Object, con. constructor) ;}}); 1.7 How to retain the constructor in section 1.6. When the constructor value is important, we need to save the value of this constructor. At this time, we can. in prototype, override the constructor attribute and set its value to "Person. ------- However, note: Native constructor attributes cannot be enumerated. If so, constructor becomes enumerative. [Javascript] function Person () {} Person. prototype = {constructor: Person, name: "defaultName", age: 20, sayName: function () {return this. name ;}}; var con = new Person (); TestCase ("test extends", {"test con shoshould be instance of Object": function () {assertInstanceOf ("con shoud be instance of Obejct", Object, con) ;}, "test con shocould be instance of Person": function () {assertInstanceOf ("Con shoud be instance of Person", Person, con) ;}, "test con constructor shocould be equals Person": function () {assertEquals (Person, con. constructor); // The constructor is completely overwritten, so it is no longer equal to the Object, but it is still an Object instance.}, "test con constructor shocould not be equals Object": function () {assertNotEquals (Object, con. constructor) ;}, "test con constructor shoshould be same as Person": function () {assertSame (Person, con. co Nstructor) ;}, "test con constructor shocould not be same as Object": function () {assertNotSame (Object, con. constructor) ;}}); supplement: If your browser is compatible with ECMAScript5, you can use defineProperty [javascript] // to reset the constructor Object. defineProperty (Person. prototype, "constructor", {enumerable: false, value: Persons}); 1.8 attributes in the prototype object are shared by all instances. Of course, this sharing is very suitable for functions, but for some reference type attributes, the problem arises, because sometimes we do not want our reference type attributes to be shared: [javascript] function Per Son () {} Person. prototype = {name: "defaultName", age: 20, friends: ["fengfeng", "tongtong"], sayName: function () {return this. name ;}}; var person = new Person (); person. friends. push ("ty"); var person2 = new Person (); TestCase ("test property", {"test person friends. length shoshould be 3 ": function () {assertEquals (person. friends. length, 3) ;}, "test person friends [2] shocould be ty": function () {AssertEquals ("ty", person. friends [2]) ;}, "test person2 friends. length shoshould be became 3 ": function () {assertEquals (person2.friends. length, 3); // The length of person2 is also changed to 3}, "test person2 friends shocould be equals person friends": function () {assertEquals (person. friends, person2.friends); // The friends attribute of person2 has also changed }}); 1.9 how to avoid sharing the attributes of the reference type-the most common way to create a custom type using the constructor mode and the prototype mode is to combine the constructor mode and the prototype mode. The constructor mode is used to define instance attributes, while the prototype mode is used to define methods and shared attributes. [Javascript] function Person (name, age) {this. name = name; this. age = age; this. friends = ['tongg', 'feng'];} Person. prototype = {constructor: Person, sayName: function () {return this. name ;}}; var person = new Person ("tongtong", 25); var person2 = new Person ("fengfeng", 26); person. friends. push ("ty"); TestCase ("test property", {"test person friends. length shoshould be 3 ": function () {assertEqual S (person. friends. length, 3) ;}, "test person friends [2] shocould be ty": function () {assertEquals ("ty", person. friends [2]) ;}, "test person2 friends. length shoshould be 2 ": function () {assertEquals (person2.friends. length, 2); // whether the length of person2 is 2}, "test person2 friends shocould not be equals person friends": function () {assertNotEquals (person. friends, person2.friends); // The friends attribute of person2 has not changed}, "test Person2 sayName shocould be equals person sayName ": function () {assertEquals (person. sayName, person2.sayName); // person. sayName === person2.sayName}); 1.10 following the 1.9 extension ------ dynamic prototype mode [javascript] function Person (name, age) {this. name = name; this. age = age; this. friends = ['tongg', 'feng']; // method if (typeof this. sayName! = "Function") {Person. prototype. sayName = function () {return this. name ;}}} is added to the prototype only when the sayName () method does not exist. This code is executed only when the constructor is called for the first time. Modifications to the prototype can be immediately reflected in all instances. When using the dynamic prototype mode, you cannot use an object to literally rewrite the prototype. If you have already created an instance, the relationship between the existing instance and the new prototype is cut off. 1.11 The so-called secure object in the secure constructor Mode means that there is no public attribute and its method does not reference this object, secure objects are best suited to some security environments (this and new are not allowed in these environments), or to prevent data from being changed by other applications. Security constructor has two features: the instance method of the newly created object does not reference this, the use of constructor without the new operator does not affect the object created in constructor mode and the constructor. Therefore, the instanceof operator has no significance for this object. [Javascript] function Person (name, age) {var o = new Object (); o. sayName = function () {return name;}; return o ;}; var person = Person ("tongtong", "25"); TestCase ("test property ", {"test person sayName shocould be tongtong": function () {assertEquals (person. sayName (), "tongtong") ;}, "test person is not instanceof Person": function () {assertNotInstanceOf (Person, person );}});
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.