摘要:原型与原型链一在了解原型之前需要提前了解的。构造函数能很好的解决这个问题。构造函数自定义构造函数,可以自定义对象类型的属性和方法。二原型模式如下,与构造函数模式不同的是,原型模式的每个实例都是访问同一属性同一函数,,函数不用重新创建。
原型与原型链
一.在了解原型之前需要提前了解的。
1.工厂模式:创建一个函数,用特定的接口创建对象的细节。
//现在要创建两个包含 “name”和“age”的对象, let tom ={name:"Tom",age:16} let lily = { name : "Lily",age:18} ……//所示数量足够具大 ,对象足够大 ,会花费大量的时间。下面的工厂模式能 很好的解决这一问题
//工厂的就是只流水线不是所有都是要人工,节约人力成本。 function person(name,age){ let obj = {}; //创建一个对象 ; obj.name = name ; //为对象添加细节 obj.age = age ; obg.sayHello= function (){ alert ("Hello"+this.name) }; return obj;} //返回这个对象 let tom = person("Tom",16); let lily = person("Lily",18)
工厂函数的优势:避免的大量的重复代码;
工厂函数的劣势:其创建的对象不能标志为一种特定的类型,没有解决对象识别的问题,不知道对象的类型。构造函数能很好的解决这个问题。
2.构造函数:自定义构造函数,可以自定义对象类型的属性和方法。
function Person(name,age){ this.name = name ; //为对象添加细节 this.age = age ; this.sayHello= function (){ alert ("Hello"+this.name) }; let tom = new Person("Tom",16); let lily =new Person("Lily",18)
new的过程做了三件事①创建了一个对象;②将this指向这个对象;③返回这个对象;
两个实例对象都有一个属性constructor(构造函数),指向Person;这就是可以通过constructor判断对象类型的原理。
存在的问题:构造函数的每个方法都要在实例上重新创建一遍,虽然函数名是一样的,但是不相等的。
二.原型模式
1.如下,与构造函数模式不同的是,原型模式的每个实例都是访问同一属性同一函数,,函数不用重新创建。
function Person () { this.x = 100; } Person.prototype.name = "Tom"; Person.prototype.age = 18; Person.prototype.sayHello = function (){ alert(`Hello${this.name}`) } let Tom = new Person() Tom.sayHello()
2.原型对象
①每个函数数据类型(普通函数,类)上,都有一个属性,叫prototype,是一个对象,这个函数指向函数的原型对象;
②prototype这个对象上,自带一个属性,constructor指向当前这个类;
③当为实例添加属性时,这个属性会屏蔽原型对象中保存的同名属性,但是事实阻止访问,并没有修改那个属性,若将同名的实例属性设置为null,同样会屏蔽,但是若用delete,则可以删除实例属性,可以重新访问原型中的属性。
alert(Tom.age); //18 let Tom.age = 20; alert(Tom.age); //20 delete Tom.age; alert(Tom.age); //18
④属性分为两种,来自实例(或者是构造函数)或是原型,原型上的属性和方法都是共有的,构造函数中的属性方法都是私有的,构造函数中的this都是实例。为什么私有属性(来自实例的属性)的查找等级要高呢?这就涉及到原型链。
3.原型链:每个对象数据类型(普通对象,prototype,实例)都有一个属性,叫做__proto__;
比如我们console.log(Tom.age)的查找过程是怎样的呢?①首先在私有空间内查找age属性,私有空间的属性包括自身的属性和从类那里继承的属性,
②找不到的话:通过__proto__去当前实例所属类的原型上进行查找,找到的话,说明是共有属性;
③还找不到的话:继续通过__proto__去当前实例所属类的原型进行查找,找不到将继续通过__proto__一直找到Object。
④曲线①代表Person的原型对象;曲线②中,实例Tom通过__proto__指向Tom所属类(Person)的原型(Person Prototype);曲线③中,Person的原型对象通过__proto__找到Person对象的所属类,也就是Object(函数也是对象类,万物皆对象),指向它的原型(ObjectPrototype) ;曲线5中,指向Obeject所属类的原型,它的类就是它自己,所以此时不在有__proto__整个属性查找结束,这就是原型链的查找过程。
⑤通过hasOwnProperty来判断属性,这个方法就是通过④中的查找过程,在基类Object中找到的。 判断属性是否在对象上“name” in Tom,其中in的查找过程也是通过上述的查找过程。
function hasPrototypeProperty(object,attr){ return !object.hasOwnProperty(attr) && (attr in object);}
4.关于原型需要注意的几点
①使用简单原型语法的时候,注意constructor的指向问题,
Person.prototype={ //此时constructor指向Object构造函数 name : "Tom", age:18 } Person.prototype={ //此时constructor指向Person constructor:Person, name : "Tom", age:18 }
②添加和修改原型的属性和方法都能立即在所有对象实例中反应出来(即使先创建实例后修改原型);但是如果重写整个原型对象,创建在前的实例并不能获得重写后的属性或方法。这是因为重写原型之后是新生成原型对象,和声明在前的任何已经存在的实例都没有关系。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/84318.html
摘要:原型链与继承当谈到继承时,只有一种结构对象。如果对该图不怎么理解,不要着急,继续往下看基于原型链的继承对象是动态的属性包指其自己的属性。当使用操作符来作用这个函数时,它就可以被称为构造方法构造函数。 原型链与继承 当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为proto)指向它的原型对象(prototype)。该原型对象也...
摘要:写在前面如果说是一本武学典籍,那么原型链就是九阳神功。那么,如何修炼好中的九阳神功呢真正的功法大成的技术是从底层上去理解,那种工程师和码农的区别就在于对底层的理解,当你写完一行代码,或者你遇见一个解决的速度取决于你对底层的理解。 写在前面 如果说JavaScript是一本武学典籍,那么原型链就是九阳神功。在金庸的武侠小说里面,对九阳神功是这样描述的:练成「九阳神功」后,会易筋洗髓;生出...
摘要:写在前面如果说是一本武学典籍,那么原型链就是九阳神功。那么,如何修炼好中的九阳神功呢真正的功法大成的技术是从底层上去理解,那种工程师和码农的区别就在于对底层的理解,当你写完一行代码,或者你遇见一个解决的速度取决于你对底层的理解。 写在前面 如果说JavaScript是一本武学典籍,那么原型链就是九阳神功。在金庸的武侠小说里面,对九阳神功是这样描述的:练成「九阳神功」后,会易筋洗髓;生出...
摘要:写在前面如果说是一本武学典籍,那么原型链就是九阳神功。那么,如何修炼好中的九阳神功呢真正的功法大成的技术是从底层上去理解,那种工程师和码农的区别就在于对底层的理解,当你写完一行代码,或者你遇见一个解决的速度取决于你对底层的理解。 写在前面 如果说JavaScript是一本武学典籍,那么原型链就是九阳神功。在金庸的武侠小说里面,对九阳神功是这样描述的:练成「九阳神功」后,会易筋洗髓;生出...
阅读 2016·2023-04-25 17:48
阅读 3552·2021-09-22 15:37
阅读 2832·2021-09-22 15:36
阅读 5666·2021-09-22 15:06
阅读 1613·2019-08-30 15:53
阅读 1384·2019-08-30 15:52
阅读 674·2019-08-30 13:48
阅读 1090·2019-08-30 12:44