您好,欢迎访问一九零五行业门户网

如何创建一个对象的方法及原型对象了解一下

很多小伙伴在学习前端的时候会遇到对象创建的难题,让我来教大家一些方法,希望大家耐心学习哦。
一、创建一个对象的方法
1.工厂模式
在函数中创建对象,并给这个对象添加属性,然后在这个函数中返回这个对象。在函数外部调用这个函数来创建对象的实例。
function createperson(name,age,job){ var o=new object();//在函数内部创建一个对象 o.name=name; o.age=age; o.job=job; o.sayname=function(){ alert(this.name); }; return o;//在函数内部返回这个对象}var person1=createperson("xiaowang","22","workers");//在函数外部创建对象的实例,不用newvar person1=createperson("xiaoliu","22","workers");
问题:没有解决对象的识别问题(不能知道一个对象的类型)
2.构造函数模式(可以用来创建特定类型的对象)
function person(name,age,job){//注意构造函数开头的字母应该大写//构造函数中使用this this.name=name; this.age=age; this.job=job; this.sayname=function(){ alert(this.name); }}var person1=new person("xiao",22,"tech");//使用new创建实例var person2=new person("li",32,"sin");
与工厂模式的不同之处:
(1)没有显示的创建对象
(2)直接将属性和方法赋值给this指向的对象
(3)没有return 语句
这两个实例都有一个constructor属性,指向person。
构造函数可以识别其实例是什么类型的对象,使用instanceof操作符更可靠一些。
问:构造函数和普通函数有什么不同?
答:用new操作符来调用的就是构造函数,不用new来调用的是普通函数。
构造函数的问题:每个方法都要在每个实例上重新创建一遍。
3.原型模式
将对象实例所共享的属性和方法不放在构造函数中,而是全部放在原型对象之中。
function person(){ };//构造函数什么也不设置person.prototype.name="xiao";//全部都放在原型对象上person.prototype.age=22;person.prototype.job="stu"'person.prototype.sayname=function(){ alert(this.name);}var person1=new person();var person2=new person();console.log(person1.sayname==person2.sayname);//true
原型模式的问题:对于包含应用类型值的属性来说,由于原型模式的共享性,改变一个实例的该引用类型值改变,则其他的实例的该属性值也被改变了。
function person={}person.prototype={ constructor:person, name:"nick", age:29, friends:['a','b'];//引用类型的值 sayname:function(){ alert(this.name); }}var person1=new person();var person2=new person();//想要改变person1实例的friends属性person1.friends.push("c);alert(person1.friends);//["a","b","c"]alert(person2.friends);//["a","b","c"];alert(person1.friends==person2.friends);//true;
4.组合模式(构造函数和原型)
构造函数定义实例的属性,原型定义方法和共享的属性。
function person(name,age,job){ this.name=name; this.age=age; this.job=job;}person.prototype={ constructor:person, sayname:function(){ alert(this.name) }}
二.原型对象的理解 1.理解
每个构造函数person都有一个prototype属性指向它的原型对象,既原型对象为person.prototype;而每个原型对象中有一个constructor方法,用来指回构造函数person。另外,调用构造函数创建的实例person1,有一个[[prototype]]属性(_proto_),也指向构造函数的原型对象。 注意,连接发生在实例和构造函数的原型对象之间!而实例和构造函数没有任何关系。
isprototypeof()方法:检测原型对象和实例是否有原型连接的关系
person.prototype.isprototypeof(person1);//true
object.getprototypeof()方法:该方法返回[[prototype]]的值,既返回一个实例的原型对象。
object.getprototypeof(person1);// person.prototype
注意:一定要先设置构造函数的原型对象,再new实例。(原型的动态性)
实例:
function person(){ } var friend=new person(); person.prototype={ constructor:person, name:'nick', age:29, job:'student', sayname:function () { alert(this.name); } }; friend.sayname();//error
这样的话,person的原型被重写了:p.157
2.属性的访问
问:原型([[prototype]])引用有什么作用?
答:当引用对象的属性的时候,会触发底层的[[get]]操作。对于默认的[[get]]操作来说,第一步是检查对象本身是否有这个属性,如果有的话就使用它,如果没有的话,这时候[[prototype]]链就派上用场了。如果对象本身没有所要的属性的时候,就继续沿着整条原型链查找,找到的话就返回该属性的值,找不到的话就返回undefined。
for...in... 遍历对象的原理和查找[[prototype]]链类似。使用in操作符来检查属性在对象中是否存在时,也会检查对象的整条原型链(不论属性是否被枚举)。
[[prototype]]原型链的最顶端设置为object.prototype对象。
3.属性的设置与屏蔽
myobject.foo="bar";//设置属性foo
step1:当myobject对象中有foo这个属性的时候,则直接将foo修改为“bar”;
step2:当foo属性既存在于myobject,又存在于原型链上,则myobject上foo属性会屏蔽原型链上所有的foo属性;
step3:当myobject对象中没有foo这个属性的时候,则会往上查找而存在于myobject的原型链;
3.1如果[[prototype]]链上层存在foo属性,并且其没有标记为只读(writable:false),那么在myobject上直接添加一个foo属性,它是屏蔽属性;
var myobject={ };myobject.prototype={ foo:"c"};myobject.foo="b";console.log(myobject.foo);//b

3.2如果foo属性被标记为只读,那么无法在myobject上修改已有属性或创建屏蔽属性。如果在严格模式下会抛出错误。
var myobject={};myobject.prototype={ foo:"c" };object.defineproperty(myobject,"foo",{ writable:false})myobject.foo="b";console.log(myobject.foo);//undefined
3.3如果在[[prototype]]上存在foo并且是一个setter,则一定会调用这个setter。foo不会被添加到myobject,也不会重新定义setter这个属性。
var myobject={ };myobject.prototype={ //foo是一个setter set foo(val){ alert(this.val); }}myobject.foo="f";console.log(myobject.foo)//f foo还是原来的setter函数,没有被修改
如果在3.2和3.3这两种情况下,则不能使用=操作符在赋值,而是使用object.defineproperty(...)方法来添加,
step4:如果myobject对象和原型链上都没有foo属性的时候,直接添加到myobject上。
var myobject={ };myobject.prototype={ foo:"c"};myobject.foo="b";console.log(myobject.foo);//b

4.属性的修改
对象实例可以修改对象原型的属性值吗?
答:分两种情况:一:当原型里的属性是值类型的话,不会被修改;
function classa(){}; classa.prototype.num=4;//num为值类型 const a=new classa(); a.num=3; const b=new classa(); console.log(b.num);
二:当原型里的属性是引用类型的话,则会被修改。
function classa(){}; classa.prototype.obj={ num:4//num在object中,是引用类型 }; const a=new classa(); a.obj.num=3; const b=new classa(); console.log(b.obj.num);
相关推荐:
javascript 基于原型的对象(创建、调用)_js面向对象
 js如何创建对象?js中创建对象的方法(附代码)
以上就是如何创建一个对象的方法及原型对象了解一下的详细内容。
其它类似信息

推荐信息