如何创建一个对象的方法及原型对象了解一下
很多小伙伴在学习前端的时候会遇到对象创建的难题,让我来教大家一些方法,希望大家耐心学习哦。
一、创建一个对象的方法
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");//在函数外部创建对象的实例,不用new var 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面向对象
以上是如何创建一个对象的方法及原型对象了解一下的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

股票分析必备工具:学习PHP和JS绘制蜡烛图的步骤,需要具体代码示例随着互联网和科技的快速发展,股票交易已经成为许多投资者的重要途径之一。而股票分析是投资者决策的重要一环,其中蜡烛图被广泛应用于技术分析中。学习如何使用PHP和JS绘制蜡烛图将为投资者提供更多直观的信息,帮助他们更好地做出决策。蜡烛图是一种以蜡烛形状来展示股票价格的技术图表。它展示了股票价格的

人脸检测识别技术已经是一个比较成熟且应用广泛的技术。而目前最为广泛的互联网应用语言非JS莫属,在Web前端实现人脸检测识别相比后端的人脸识别有优势也有弱势。优势包括减少网络交互、实时识别,大大缩短了用户等待时间,提高了用户体验;弱势是:受到模型大小限制,其中准确率也有限。如何在web端使用js实现人脸检测呢?为了实现Web端人脸识别,需要熟悉相关的编程语言和技术,如JavaScript、HTML、CSS、WebRTC等。同时还需要掌握相关的计算机视觉和人工智能技术。值得注意的是,由于Web端的计

如何使用PHP和JS创建股票蜡烛图股票蜡烛图是股票市场中常见的一种技术分析图形,通过绘制股票的开盘价、收盘价、最高价和最低价等数据,帮助投资者更直观地了解股票的价格波动情况。本文将教你如何使用PHP和JS创建股票蜡烛图,并附上具体的代码示例。一、准备工作在开始之前,我们需要准备以下环境:1.一台运行PHP的服务器2.一个支持HTML5和Canvas的浏览器3

随着互联网金融的迅速发展,股票投资已经成为了越来越多人的选择。而在股票交易中,蜡烛图是一种常用的技术分析方法,它能够显示股票价格的变化趋势,帮助投资者做出更加精准的决策。本文将通过介绍PHP和JS的开发技巧,带领读者了解如何绘制股票蜡烛图,并提供具体的代码示例。一、了解股票蜡烛图在介绍如何绘制股票蜡烛图之前,我们首先需要了解一下什么是蜡烛图。蜡烛图是由日本人

将MySQL查询结果数组转换为对象的方法如下:创建一个空对象数组。循环结果数组并为每一行创建一个新的对象。使用foreach循环将每一行的键值对赋给新对象的相应属性。将新对象添加到对象数组中。关闭数据库连接。

PHP中,数组是有序序列,以索引访问元素;对象是具有属性和方法的实体,通过new关键字创建。数组访问通过索引,对象访问通过属性/方法。数组值传递,对象引用传递。

js和vue的关系:1、JS作为Web开发基石;2、Vue.js作为前端框架的崛起;3、JS与Vue的互补关系;4、JS与Vue的实践应用。

PHP中的Request对象是用于处理客户端发送到服务器的HTTP请求的对象。通过Request对象,我们可以获取客户端的请求信息,比如请求方法、请求头信息、请求参数等,从而实现对请求的处理和响应。在PHP中,可以使用$_REQUEST、$_GET、$_POST等全局变量来获取请求的信息,但是这些变量并不是对象,而是数组。为了更加灵活和方便地处理请求信息,可
