Home >Web Front-end >JS Tutorial >Introduction to JavaScript prototypes and prototype chain methods (code examples)
This article brings you an introduction to JavaScript prototypes and prototype chain methods (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
1. Question
How to accurately determine whether a variable is an array
Write an example of prototype chain inheritance
Other ways of inheritance implementation
es6 What is the underlying principle of inheritance
Describe the process of new an object
How to use the prototype chain in zepto and other source codes
2. Knowledge points
2.1 Constructor
Features: Starting with a capital letter
function Foo(name,age){ //var obj = {} //this = {} this.name = name; this.age = age; this.class = 'class1' // return this } var f1 = new Foo('liming',19);
Extension
var o = {} is the syntactic sugar of var o = new Object()
var a = [] is the syntactic sugar of var a = new Array()
function Foo(){} is equivalent to var Foo = new Function(){}
2.2 Prototype rules
Five rules:
1. All reference types (objects, arrays, functions) All have object characteristics, that is, attributes can be freely extended
2. All reference types (objects, arrays, functions) have a __proto__ (implicit prototype) attribute, which is an ordinary object
3. All functions have prototype (explicit prototype) attributes and are also ordinary objects
4. All reference types (objects, arrays, functions) __proto__ value points to the prototype of its constructor
5. When trying to get the attributes of an object, if the variable itself does not have this attribute, it will go to its __proto__ to find it
for (var key in object) { //高级浏览器中已经屏蔽了来自原型的属性 //建议加上判断保证程序的健壮性 if (object.hasOwnProperty(key)) { console.log(object[key]); } }
2.3 Prototype chain
obj.__ proto . proto . proto __ ...
Object.prototype === null
instanceof is used for judgment Which constructor does the reference type belong to
obj instanceob Foo
Actual meaning: Determine whether Foo.prototype is on the prototype chain of obj
3. Question answer
3.1 How to accurately determine whether a variable is an array
arr instanceof Array
##3.2 Write an example of prototype chain inheritanceEncapsulate dom query
function Elem(id){ this.elem = document.getElementById(id); }; Elem.prototype.html = function(val){ var elem = this.elem; if (val) { elem.innerHTML = val; return this; }else{ return elem.innerHTML; } } Elem.prototype.on = function(type,fun){ var elem = this.elem; elem.addEventListener(type,fun); return this; } var p1 = new Elem('id1'); p1.html("test").on('click',function(){ console.log('点击'); })
3.3 Other ways of inheritance implementation
3.3.1 Prototypal inheritancevar obj = { 0:'a', 1:'b', arr:[1] } function Foo(arr2){ this.arr2 = [1] } Foo.prototype = obj; var foo1 = new Foo(); var foo2 = new Foo(); foo1.arr.push(2); foo1.arr2.push(2); console.log(foo2.arr); //[1,2] console.log(foo2.arr2); //[1]Advantages: Simple implementationDisadvantages:1. Unable to pass parameters to the parent class constructor 2. When new two objects are used at the same time, when a reference type attribute in the prototype of one object is changed, the attribute of the other object will also be modified. Because the reference properties from the prototype object are shared by all instances. 3.3.2 Structural inheritance
function Super(b){ this.b = b; this.fun = function(){} } function Foo(a,b){ this.a = a; Super.call(this,b); } var foo1 = new Foo(1,2); console.log(foo1.b);
function Super(){ // 只在此处声明基本属性和引用属性 this.val = 1; this.arr = [1]; } // 在此处声明函数 Super.prototype.fun1 = function(){}; Super.prototype.fun2 = function(){}; //Super.prototype.fun3... function Sub(){ Super.call(this); // 核心 // ... } Sub.prototype = new Super();
function Super(b){ this.b = b; this.fun = function(){} } Super.prototype.c = function(){console.log(1111)} function Foo(a,b){ this.a = a; Super.call(this,b); } Foo.prototype = Super.prototype; //修复构造函数: var foo1 = new Foo(1,2);Disadvantages: It is impossible to distinguish whether the instance is created by the parent class or not. Subclass creation3.3.4 Parasitic combination inheritance
function Super(b){ this.b = b; } Super.prototype.c = function(){console.log(1111)} function Foo(a,b){ this.a = a; Super.call(this,b); } var f = new Function(); f.prototype = Super.prototype; Foo.prototype = new f(); //等同于 Foo.prototype = Object.create(Super.prototype); var foo1 = new Foo(1,2);
Foo.prototype.constructor = FooThis solution cannot be used for the above combined optimization method , because the subclass and parent class refer to the same prototype object, modifications will be modified at the same time. Summary: Inheritance is mainly to realize the reuse of parent class methods and attributes by subclasses. Reference properties from the prototype object are shared by all instances, so we want to avoid inheriting properties from the prototype. You can inherit the attributes and methods of the parent class constructor through the call function in the constructor, but the instance instantiated in this way will store the parent class methods multiple times, which affects performance. Through combined inheritance, we use call inheritance properties and the prototype inheritance method to solve the above two problems, but the object instantiated in this way will store two copies of the properties in the parent class constructor. Constructing a new object using the prototype of the parent class as the prototype of the subclass solves the problem of multiple storage, so the final parasitic combination inheritance is the best inheritance method. Its disadvantage is that it is more troublesome to write. . 3.3.6 Inheritance implementation in node source code
function inherits(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; function Stream(){ //... } function OutgoingMessage() { Stream.call(this); //... } inherits(OutgoingMessage, Stream); OutgoingMessage.prototype.setTimeout = ...
ctor.prototype=Object.create(superCtor.prototype,{.....});This method actually does the work of our parasitic combination inheritance above
var f = new Function(); f.prototype =superCtor.prototype; return new f();The following parameters are to add attributes to the prototype object, optional attributes (not required), that is, put Serves itself as the constructor of a newly created object.
value: 表示constructor 的属性值; writable: 表示constructor 的属性值是否可写;[默认为: false] enumerable: 表示属性constructor 是否可以被枚举;[默认为: false] configurable: 表示属性constructor 是否可以被配置,例如 对obj.a做 delete操作是否允许;[默认为: false]3.4 How to implement es6 inheritanceRefer to my article: https://segmentfault.com/a/11...
创建一个对象
{}._proto_ = 构造函数.prototype
this指向这个对象
执行代码即对this赋值
返回this
var Zepto = (function(){ var $,zepto = {} // ...省略N行代码... $ = function(selector, context){ return zepto.init(selector, context) } zepto.init = function(selector, context) { var dom // 针对参数情况,分别对dom赋值 // 最终调用 zepto.Z 返回的数据 return zepto.Z(dom, selector) } fnction Z(dom, selector) { var i, len = dom ? dom.length : 0 for (i = 0; i < len; i++) this[i] = dom[i] this.length = len this.selector = selector || '' } zepto.Z = function(dom, selector) { return new Z(dom, selector) } $.fn = { // 里面有若干个工具函数 } zepto.Z.prototype = Z.prototype = $.fn // ...省略N行代码... return $ })() window.Zepto = Zepto window.$ === undefined && (window.$ = Zepto)
The above is the detailed content of Introduction to JavaScript prototypes and prototype chain methods (code examples). For more information, please follow other related articles on the PHP Chinese website!