热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基本二:javascript面向对象、建立对象、原型和继续总结(上)

媒介:本文主要总结一下javascript建立对象的要领、原型、原型链和继续,然则先从建立对象的几种要领最先,延伸到原型情势建立对象以及别的情势。继续原本想一块写了,发明太多内容了

媒介:本文主要总结一下Javascript建立对象的要领、原型、原型链和继续,然则先从建立对象的几种要领最先,延伸到原型情势建立对象以及别的情势。继续原本想一块写了,发明太多内容了,放到下里总结。

1.建立对象

(1)两个基础要领

建立对象最基础的两个要领是:Object组织函数对象字面量

//Object组织函数体式格局
var person = new Object();
person.name = "Jack";
person.age = 12;
person.sayName = function(){
alert(this.name);
}; //字面量体式格局
var person = {
name: "Jack",
age: 14,
job: "码农",
sayName: function(){
alert(this.name);
}
};

(2)工场情势

上述两个基础要领的瑕玷是:运用统一个接口建立许多对象,会发作大批的。针对这个瑕玷,看下面
道理是用函数来封装以特定接口建立对象的细节

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("Jack",15,"码农");
var person2 = createPerson("rose",12,"顺序媛");

函数createPerson能吸收参数构建一个包含一切属性的对象,而且可以用很少的代码不停的建立多个对象,然则由于它被函数所封装,暴露的接口不能有用的辨认对象的范例(即你不知道是Object照样自定义的什么对象)。

(3)组织函数情势

function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person("Jack",15,"码农"); //满满的java复古风
var person2 = new Person("Rose",15,"顺序媛");

  1. 与工场情势比拟,组织函数情势用Person()函数替代了createPerson()函数,而且没有显现的建立对象,直接把属性和要领赋值给了this对象。

  2. 要建立Person的实例,必需运用new关键字。

  3. person1和person2都是Person的实例,这两个对象都有一个constructor(组织函数)属性,该属性指向Person。 person1.cOnstructor== Person; //true

  4. person1即是Person的实例又是Object的实例,背面继续原型链会总结。

(3).1组织函数的运用

//当作组织函数运用
var person1 = new Person("Jack",15,"码农");
person1.sayName(); //"Jack"

//当作一般函数运用
Person("Jack",16,"码农"); //注重:此处增加到了window
window.sayName(); //"Jack"

//在另一个对象的作用域中挪用
var o = new Object();
Person.call(o,"Jack",12,"码农");
o.sayName(); //"Jack"

  1. 第一种当作组织函数运用就不多说了

  2. 当在全局作用域中挪用Person("Jack",16,"码农");时,this对象老是指向Global对象(浏览器中是window对象)。因而在实行完这句代码后,可以经由历程window对象来挪用sayName()要领,而且返回“Jack”。

  3. 末了也可以运用call()或许apply()在某个特别对象的作用域中挪用Person()函数

(3).2存在的题目

在(3)组织函数情势的代码中,对象的要领sayName的功用都一样,就是alert当前对象的name。当实例化Person以后,每一个实例(person1和person2)都有一个名为sayName的要领,然则两个要领不是统一个Function实例。不要忘了,js中函数是对象,所以每一个实例都包含一个差别的Function实例,但是建立两个功用完整一样的Function实例是完整没有必要的。因而可以把函数定义转移到组织函数外。
以下代码:


function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName(){
alert(this.name);
}

//实例化对象
var person1 = new Person("Jack",15,"码农"); //满满的java复古风
var person2 = new Person("Rose",15,"顺序媛");

然则如许依旧存在题目:

  1. 为了让Person的实例化对象同享在全局作用域中定义的统一个sayName()函数,我们把函数sayName()定义在全局作用域中,并经由历程指针sayName指向组织函数,所以在全局作用域中的sayName()只能被特定对象挪用,全局作用域名不符实,且污染全局变量。

  2. 而且如果对象须要许多种要领,那末就要定义许多全局函数,关于对象就没有封装性,而且污染全局。

2.原型

(1)原型情势建立对象

  1. js差别于强范例言语的java,java建立对象的历程是由类(笼统)到类的实例的历程,是一个从笼统到详细的历程。

  2. Javascript则差别,其用原型建立对象是一个详细到详细的历程,即以一个现实的实例为底本(原型),去建立另一个实例对象。

所以用原型情势建立对象有两种体式格局:

1.Object.create()要领
Object.create:它吸收两个参数,第一个是用作新对象原型的对象(即原型),一个是为新对象定义分外属性的对象(可选,不经常使用)。

var Person = {
name:"Jack",
job:"码农"
};
//通报一个参数
var anotherPerson = Object.create(Person);
anotherPerson.name //"Jack"
//通报两个参数
var yetPerson = Object.create(Person,{name:{value:"Rose"}});
yetPerson.name; //Rose

2.组织函数要领建立对象

  1. 任何一个函数都有一个prototype属性(是一个指针),指向经由历程组织函数建立的实例对象原型对象,原型对象可以让一切对象实例同享它所包含的属性和要领。

  2. 因而没必要在组织函数中定义对象实例的信息,而是将这些属性和要领直接增加到原型对象中,从而被实例对象多继续(继续背面总结)

//第一步:用组织函数建立一个空对象
function Person(){
}
//第二步:给原型对象设置属性和要领
Person.prototype.name = "Jack";
Person.prototype.age = 20;
Person.prototype.job = "码农";
Person.prototype.sayName = function(){
alert(this.name);
};
//第三步:实例化对象后,便可继续原型对象的要领和属性
var person1 = new Person();
person1.sayName(); //Jack var person2 = new Person();
person2.sayName(); //Jack alert(person1.sayName == person2.sayName); //true

person1和person2说接见的是统一组属性和统一个sayName()函数。

(2)明白原型对象

  1. 只需建立一个函数,就会为该函数建立一个prototype属性,这个属性指向函数的原型对象。

  2. 一切原型对象都邑自动获得一个constructor(组织函数)属性,这个属性包含一个指向prototype属性地点函数的指针。

  3. 当挪用组织函数建立一个新的实例对象后,该实例内部会有一个指针([prototype]/_proto_),指向组织函数的原型对象。以下图:
    《基本二:Javascript面向对象、建立对象、原型和继续总结(上)》

上图中 :

  1. Person.prototype指向了原型对象,而Person.prototype.construstor又指回了Person。

  2. 注重视察原型对象,除了包含constructor属性以外,还包含厥后增加的别的属性,这就是为何每一个实例化后的对象,虽然都不包含属性和要领,然则都包含一个内部属性指向了Person.prototype,能获得原型中的属性和要领。

(3)推断一个实例对象的原型

这个要领叫:Object.getPrototypeOf(),以下例子:

alert(Object.getPrototypeOf(person1) == Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //”Jack”

  1. 这个要领可以很轻易的获得一个对象的原型

  2. 还可以应用这个要领获得原型对象中的name属性的值。

(3)搜刮属性的历程

  1. 当我们在建立实例化的对象以后,挪用这个实例化的对象的属性时,会前后实行两次搜刮。

  2. 第一次搜刮实例person1有name属性吗?没有举行第二次搜刮

  3. 第二次搜刮person1的原型有name属性吗?有就返回。

因而举行一次思索,如果对实例举行属性重写和要领掩盖以后,接见实例对象的属性和要领会显现哪一个?实例对象的照样对象原型的?

function Person(){
} Person.prototype.name = "Jack";
Person.prototype.age = 20;
Person.prototype.job = "码农";
Person.prototype.sayName = function(){
alert(this.name);
}; var person1 = new Person();
var person2 = new Person(); person1.name = "Rose";
alert(person1.name); //Rose
alert(person2.name); //Jack

  1. 当为对象实例增加一个属性时,这个属性就会屏障原型对象中保留的同名属性。

  2. 然则这个属性只会阻挠我们接见原型中的谁人属性,而不会修正谁人属性
    3.运用delete操作符可以删除实例属性,从而从新接见原型中的属性。

function Person(){
}
Person.prototype.name = "Jack";
Person.prototype.age = 20;
Person.prototype.job = "码农";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person(); person1.name = "Rose";
alert(person1.name); //Rose --来自实例
alert(person2.name); //Jack --来自原型 delete person1.name;
alert(person1.name); //Jack --来自原型

(4)推断接见的究竟是对象照样原型属性

  1. hasOwnProperty()可以检测一个属性是存在于实例中,照样原型中,只要在给定属性存在于对象实例中,才会返回true。

    person1.hasOwnProperty("name"); //假定name存在于原型,返回false

  2. in操作符会在经由历程对象可以接见给定属性时返回true,不管该属性是存在于实例中照样原型中

    "name" in person1 //true

所以经由历程这两个可以封装一个hasPrototypeProperty()函数肯定属性是否是原型中的属性。

function hasPrototypeProperty(object,name){
return !object.hasOwnProperty(name) && (name in object);
}

(5)更简朴的原型语法

前面每次增加一个属性和要领都要写一次Person.prototype,为了轻便可以直接如许

function Person(){
}
Person.prototype = {
name:"Jack",
age:20,
job:"码农",
sayName:function(){
alert("this.name");
}
};

  1. 上述代码直接将Person.prototype设置为即是一个以对象字面量情势建立的新对象

  2. 上述这么做时:constructor属性就不再指向Person了。

  3. 本质上完整重写了默许的prototype对象,因而constructor属性也就变成了新对象的constructor属性(指向Object组织函数)。

  4. 因而如果constructor值很主要,可以在Person.prototype中设置回恰当的值:
    如上例中可以增加:constructor:Person,

(6)原型的动态性

我们对原型对象所做的任何修正都邑马上从实例上反应出来-纵然先建立实例对象后修正原型也云云

var friend = new Person();
Person.prototype.sayHi = function(){
alert("Hi");
};
friend.sayHi(); //"Hi"

只管可以随时为原型增加属性和要领,而且修正能马上在实例对象中体现出来,然则如果重写全部原型对象,就不一样了。看下面例子:

function Person(){
}
var friend = new Person();
Person.prototype = {
constructor:Person,
name:"Jack",
age:20,
sayName:function(){
alert(this.name);
}
};
friend.sayName(); //error

  1. 上述代码先建立了一个Person实例,然后又重写了其原型对象,在挪用friend.sayName()时发作毛病。

  2. 由于friend指向的原型中不包含以该名字定名的属性。关联以下图:
    《基本二:Javascript面向对象、建立对象、原型和继续总结(上)》

(7)原型对象的题目

  1. 省略了为组织函数初始化参数这一环节,结果是一切实例都获得雷同的属性,但题目不大,可认为实例对象重写属性来处理。
    2.然则,关于包含援用范例值的属性来讲,题目就比较突出了,由于援用范例中,属性名只是一个指针,在实例中重写该属性并没有作用。指针一直指向原本的。

以下例子:

function Person(){}
Person.prototype = {
constructor:Person,
name:"Jack",
job:"码农",
friends:["路人甲","路人乙","路人丙"], };
var person1 = new Person();
var person2 = new Person(); person1.friends.push("路人丁");
alert(person1.friends); //["路人甲","路人乙","路人丙","路人丁"]
alert(person2.friends); //["路人甲","路人乙","路人丙","路人丁"]
alert(person1.friends === person2.friends); //true

上面这个,如果每一个实例对象的援用值属性不一样,则没法修正。

3.组合运用组织函数和原型情势

  1. 组织函数情势用于定义实例属性

  2. 原型情势用于定义要领和同享的属性

以下代码:

function Person(name,age,job){
this.name = name;
this.job = job;
this.age = age;
this.friends = ["路人甲","路人乙"];
} Person.prototype = {
constructor:Person,
sayName: function(){
alert(this.name);
}
}
var person1 = new Person("Jack", 20, "码农");
var person2 = new Person("Rose", 20, "顺序媛"); person1.friends.push("路人丁");
alert(person1.friends); //["路人甲","路人乙","路人丁"]
alert(person2.friends); //["路人甲","路人乙"]
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true

4.寄生组织函数情势

该情势基础思想是建立一个函数,该函数作用仅仅是封装建立对象的代码,然后返回新建立的对象。

function Person(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 friend = new Person("Jack", 16, "码农");
friend.sayName(); //Jack

  1. 组织函数在不返回值的情况下,默许会返回新对象实例。

  2. 经由历程在组织函数末端增加一个return语句,可以重写挪用组织函数时返回的值。

这个要领的用途是:可以建立一个分外要领的特别的数组(由于原生对象Array的组织函数不能直接修正)

function SpecialArray(){
//建立数组
var values = new Array();
//增加值
values.push.apply(values,arguments);

//增加要领
values.toPipedString = function(){
return this.join("|");
};
//返回数组
return values;
}
var colors = new SpecialArray("black","red","blue");
alert(colors.toPipedString());

原本想接着写继续的,发明实在太多了,分红两篇吧。


推荐阅读
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
author-avatar
杨艳奎_718
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有