搜索
首页web前端js教程如何创建一个对象的方法及原型对象了解一下

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

一、创建一个对象的方法

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_),也指向构造函数的原型对象。 注意,连接发生在实例和构造函数的原型对象之间!而实例和构造函数没有任何关系。

20180820094357489.png

  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中创建对象的方法(附代码)

以上是如何创建一个对象的方法及原型对象了解一下的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的演变:当前的趋势和未来前景JavaScript的演变:当前的趋势和未来前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

神秘的JavaScript:它的作用以及为什么重要神秘的JavaScript:它的作用以及为什么重要Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python还是JavaScript更好?Python还是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安装JavaScript?如何安装JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。