很多小伙伴在学习前端的时候会遇到对象创建的难题,让我来教大家一些方法,希望大家耐心学习哦。

一、创建一个对象的方法

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);

相关推荐:

php中如何创建一个对象的方法,如何创建一个对象的方法及原型对象了解一下相关推荐

  1. JavaScript基础09-day11【原型对象、toString()、垃圾回收、数组、数组字面量、数组方法】

    学习地址: 谷粒学院--尚硅谷 哔哩哔哩网站--尚硅谷最新版JavaScript基础全套教程完整版(140集实战教学,JS从入门到精通) JavaScript基础.高级学习笔记汇总表[尚硅谷最新版Ja ...

  2. 初学JavaScript:js中的对象(对象+原型对象)

    文章目录 js对象详解 1.创建对象 字面量模式创建对象 构造函数模式创建对象 2.访问对象 访问属性 访问方法 3.遍历对象中的属性和属性值 4.往对象中新添属性 5.删除对象中的属性 6.Obje ...

  3. 实例对象的属性和原型对象中的属性重名问题 神奇的原型链 继承 继承案例

    实例对象的属性和原型对象中的属性重名问题 <!DOCTYPE html> <html lang="en"> <head><meta cha ...

  4. js代码中可以有java的对象吗_js原型对象与Java类的区别

    标签: 在我学习Javascript的原型对象时,我总是不自觉地拿Java的类思想来做比较,时间久了,我渐渐认识到二者有巨大的不同. 首先,类是不能直接当方法来运行,它最简便的方式是调用其静态方法:而 ...

  5. 创建一个对象的方法及原型对象

    一.创建一个对象的方法 1.工厂模式 在函数中创建对象,并给这个对象添加属性,然后在这个函数中返回这个对象.在函数外部调用这个函数来创建对象的实例. function createPerson(nam ...

  6. 背景图层和普通图层的区别_新手如何在PS中创建图层?不容错过的7种方法,你值得学习...

    昨天跟小波一起认识了PS图层的童鞋应该已经对它不陌生了,那么在了解之后就要来实践操作,毕竟实践出真知嘛.那这一章就一起来学习在PS中创建图层吧. 在PS中,图层的创建方法有很多种,包括在"图 ...

  7. MFC中动态创建控件及添加消息响应的方法实例

    动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态控件: 为了对照,我们先来看一下静态控件的创建. 放置静态控件时必须先建立一个容器,一般是对话框, ...

  8. python如何创建一个列表_在python中创建列表的最佳和/或最快方法

    在python中,据我所知,至少有3到4种方法来创建和初始化给定大小的列表: 简单循环append: my_list =[]fori inrange(50):my_list.append(0) 简单循 ...

  9. 如何批量在文件夹中建立php,怎么批量创建文件夹_一次性创建多个文件夹方法_一聚教程网...

    相信大家在平时的工作或是生活中,经常会遇到需要创建多个文件夹的问题,那么对于这种一次性创建多个文件夹的问题怎么解决呢?这里文章就给大家具体介绍下批量创建多个文件夹的问题,感兴趣的一起来了解下. 日常工 ...

最新文章

  1. C++五子棋(四)——走棋原理及权值计算
  2. 中小学将逐步推广编程教育;勒索病毒攻击部分政府部门和医院;国内外药企密集调价;微软要给Win7用户推死亡通知,这就是今天的大新闻...
  3. PaperNotes(15)-图神经网络、PyG极简版入门笔记
  4. springmvc拦截器配置
  5. 20个优秀的前端css框架
  6. 史上最硬核的rpm和dpkg依赖问题解决方案
  7. MyBatis3整合Spring3、SpringMVC3
  8. 【滤波器设计】基于matlab GUI窗函数法高通+低通+带通带阻FIR滤波器设计【含Matlab源码 072期】
  9. Playing Atari with Deep Reinforcement Learning 中文 讲解3
  10. 小白如何准备数学建模——以美赛为列
  11. html乱码原因与网页乱码解决方法
  12. java soap服务_「java调用webservice」java调用webservice接口 三种方法 - seo实验室
  13. java max 函数_Java Math max()用法及代码示例
  14. 介绍ping中的TTL是什么意思
  15. C++基础笔记——汇总版(上)
  16. 程序员显示器怎么设置成竖屏
  17. [学习笔记]什么是存储过程?
  18. 正在解析主机/打开网页慢,有可能是你的虚拟机网卡的问题
  19. Ceph 存储集群2-配置:心跳选项、OSD选项、存储池、归置组和 CRUSH 选项
  20. IPV6 DHCPV6 和 无状态 分配地址

热门文章

  1. HDU 5242 上海大都会 G题
  2. 机器学习(十六)推荐系统
  3. CSS Text Decoration
  4. 2020程序设计基础c语言答案,2020知到程序设计基础(C语言)入门篇答案全套
  5. SEO优化怎么发外链,SEO外链发布的技巧
  6. matlab电流可逆斩波电路,电流可逆斩波电路.PPT
  7. Kylin作用是什么?
  8. P1413 坚果保龄球——题解2020.10.10
  9. 软件工程(一)------软件生存周期
  10. 在Linux服务器上安装horovod安装