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("Nicholas", 29, "Software Engineer"); var person2 = createPerson("Greg", 27, "Doctor"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg"
工厂模型的方法的缺点是会产生大量重复代码!
2、构造函数模式创建对象
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg" alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true alert(person2 instanceof Object); //true alert(person2 instanceof Person); //true alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true alert(person1.sayName == person2.sayName); //false
使用new关键字创建对象会经历以下四个过程
- 1、创建一个新对象
- 2、将构造函数的作用域赋给一个新对象(因此this就指向了这个新对象)
- 3、执行构造函数的方法(为这个新对象赋值)
- 4、返回新对象
3、将构造函数当函数用
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person = new Person("Nicholas", 29, "Software Engineer"); person.sayName(); //"Nicholas" Person("Greg", 27, "Doctor"); //adds to window window.sayName(); //"Greg" var o = new Object(); Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"
构造函数当做函数使用就和普通的函数没有任何不同,它属于window对象下面添加的方法而已。由于构造函数创建的对象实际上是创建一个新对象,因此在本质上两者还是不一样的,还是分离的,他们的方法还是不一样的!
4、将共有的方法方法全局解决不一致的问题
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("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg" alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true alert(person2 instanceof Object); //true alert(person2 instanceof Person); //true alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true alert(person1.sayName == person2.sayName); //true
虽然上面的方法解决了一致的问题,但是定义的全局的方法本身属于window,那么局部和全局就没有分开!所以这个方法使用的并不多见!也不建议使用。
5、原型模式
我们创建的任何的一个函数都有一个原型对象,这个属性是一个指针,它指向一个对象,而这个对象的作用是可以有特定的类型的所有的实例共享的方法!
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true alert(Person.prototype.isPrototypeOf(person1)); //true alert(Person.prototype.isPrototypeOf(person2)); //true //only works if Object.getPrototypeOf() is available if (Object.getPrototypeOf){ alert(Object.getPrototypeOf(person1) == Person.prototype); //true alert(Object.getPrototypeOf(person1).name); //"Nicholas" }
理解原型
无论什么时候只要是创建了一个函数,就会创建一个原型属性,这个属性指向函数的原型对象。在默认的情况下,原型对象都会包含一个constructor(构造函数属性),这个属性包含一个指向prototype属性所在函数的指针!
属性读取的顺序
每当代码读取某个对象的属性时候,都会执行一次搜索,目标是具有给定名字的属性,搜索从对象的实例本身开始查找,如有则返回,没有则继续搜索该对象的原型链,直至搜索到原型链的最外层!
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name = "Greg"; alert(person1.name); //"Greg" 来自实例 alert(person2.name); //"Nicholas" 来自原型
如果删除了这个元素的实例属性
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name = "Greg"; alert(person1.name); //"Greg" ?from instance alert(person2.name); //"Nicholas" ?from prototype delete person1.name; alert(person1.name); //"Nicholas" - from the prototype
6、hasOwnProperty方法
这个方法可以检测一个属性是否存在于实例中,还是存在于原型中!hasOwnProperty是从Object继承来的,只要给定属性存在于对象实例中,才会返回true.
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); var person2 = new Person(); alert(person1.hasOwnProperty("name")); //false alert("name" in person1); //true person1.name = "Greg"; alert(person1.name); //"Greg" ?from instance alert(person1.hasOwnProperty("name")); //true alert("name" in person1); //true alert(person2.name); //"Nicholas" ?from prototype alert(person2.hasOwnProperty("name")); //false alert("name" in person2); //true delete person1.name; alert(person1.name); //"Nicholas" - from the prototype alert(person1.hasOwnProperty("name")); //false alert("name" in person1); //true
7、Object.keys() 可枚举属性方法
这个方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var keys = Object.keys(Person.prototype); alert(keys); //"name,age,job,sayName" 如果想得到所有实例的属性,无论它是否可以枚举都可以使用这个方法来获取 function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var keys = Object.getOwnPropertyNames(Person.prototype); alert(keys); //"constructor,name,age,job,sayName"
此方法高版本浏览器才支持
8、简单的原型写法
function Person(){ } Person.prototype = { name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); } }; var friend = new Person(); alert(friend instanceof Object); //true alert(friend instanceof Person); //true alert(friend.constructor == Person); //false alert(friend.constructor == Object); //true
重写了原型就等于将默认的原型方法覆盖,那么同样的构造方法也会被重写,重写的构造方法指向了Object对象!而不是原来的对象Person
如果还是想指向之前的构造方法,可以显示的指定
function Person(){ } Person.prototype = { constructor : Person, name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); } }; var friend = new Person(); alert(friend instanceof Object); //true alert(friend instanceof Person); //true alert(friend.constructor == Person); //true alert(friend.constructor == Object); //false
9、原型方法的动态添加
function Person(){ } Person.prototype = { constructor: Person, name : "Nicholas", age : 29, job : "Software Engineer", sayName : function () { alert(this.name); } }; var friend = new Person(); Person.prototype.sayHi = function(){ alert("hi"); }; friend.sayHi(); //"hi" ?works!
10、原生对象的原型方法
alert(typeof Array.prototype.sort); //"function" alert(typeof String.prototype.substring); //"function" String.prototype.startsWith = function (text) {//修改原生对象的原型方法 return this.indexOf(text) == 0; }; var msg = "Hello world!"; alert(msg.startsWith("Hello")); //true
11、组合使用构造函数和原型模式创建对象
//构造函数模式 function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } //原型模式 Person.prototype = { constructor: Person, sayName : function () { alert(this.name); } }; var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); alert(person1.friends); //"Shelby,Court,Van" alert(person2.friends); //"Shelby,Court" alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true
12、动态原型模式
function Person(name, age, job){ //properties this.name = name; this.age = age; this.job = job; //methods if (typeof this.sayName != "function"){ Person.prototype.sayName = function(){ alert(this.name); }; } } var friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName();
13、寄生构造函数模式
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("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas" function SpecialArray(){ //create the array var values = new Array(); //add the values values.push.apply(values, arguments); //assign the method values.toPipedString = function(){ return this.join("|"); }; //return it return values; } var colors = new SpecialArray("red", "blue", "green"); alert(colors.toPipedString()); //"red|blue|green" alert(colors instanceof SpecialArray);
上诉方法有一点说明下,由于它是依赖外层对象来创建一个新对象,因此不能依赖 instanceof方法来确定属性和方法的来源!它实际上和构造函数的没有关系!
14、稳妥构造函数模式
function Person(name, age, job){ var o = new Object(); o.sayName = function(){ alert(name); }; return o; } var friend = Person("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas"
此方法不依赖任何new this 关键符!如果要访问对象的方法和属性,只能通过对象已经定义好的方法来获取!
15、继承
javascript实现继承是通过原型链来实现的
function SuperType(){ this.property = true;//定义一个属性 } SuperType.prototype.getSuperValue = function(){//定义的原型方法 return this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.subproperty; }; var instance = new SubType(); alert(instance.getSuperValue()); //true alert(instance instanceof Object); //true alert(instance instanceof SuperType); //true alert(instance instanceof SubType); //true alert(Object.prototype.isPrototypeOf(instance)); //true alert(SuperType.prototype.isPrototypeOf(instance)); //true alert(SubType.prototype.isPrototypeOf(instance)); //true SubType继承SuperType的方法和属性,因此当instance可以直接调用SuperType的方法! function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); //new method SubType.prototype.getSubValue = function (){ return this.subproperty; }; //override existing method SubType.prototype.getSuperValue = function (){ return false; }; var instance = new SubType(); alert(instance.getSuperValue()); //false
上面的例子说明,重写的原型会覆盖之前继承的原型,最后返回的往往不是预期的效果
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); //使用字面量添加的方法导致上面的方法失效了 SubType.prototype = { getSubValue : function (){ return this.subproperty; }, someOtherMethod : function (){ return false; } }; var instance = new SubType(); console.log(instance); alert(instance.getSuperValue()); //error!
下面的例子也说明重写原型带来的风险
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ } //inherit from SuperType SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green,black"
原型共享导致两个不同的对象调用的同一个数据
16、借用构造函数来实现继承
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ //inherit from SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green"
传递参数
function SuperType(name){ this.name = name; } function SubType(){ //inherit from SuperType passing in an argument SuperType.call(this, "Nicholas"); //instance property this.age = 29; } var instance = new SubType(); alert(instance.name); //"Nicholas"; alert(instance.age); //29
17、组合继承方式
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ SuperType.call(this, name); this.age = age; }
18、原型继承
function object(o){ function F(){} F.prototype = o; return new F(); } var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob");
19、寄生组合式继承
function object(o){ function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //create object prototype.constructor = subType; //augment object subType.prototype = prototype; //assign object } function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ SuperType.call(this, name); this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27
以上就是今天的javascript学习小结,之后每天还会继续更新,希望大家继续关注。

Java作为一门常见的编程语言,其在IT行业中有着广泛的应用,成为了许多公司招聘中的重要技能之一。在Java开发岗位的面试中,面试官往往会问及一些常见的Java问题,以此考察应聘者的Java编程水平。本文将列举几个常见的Java面试问题及其答案,供广大应聘者参考。什么是Java虚拟机?答:Java虚拟机(JVM)是一种虚拟的计算机,可以执行Java字节码。它

PHP的面向对象编程范式为项目管理和组织提供优势随着互联网的飞速发展,各种规模的网站和应用程序如雨后春笋般涌现出来。为了满足日益增长的需求,并提高开发效率和可维护性,采用面向对象编程(Object-OrientedProgramming,简称OOP)的方法成为了现代软件开发的主流。在PHP这样的动态脚本语言中,OOP为项目管理和组织带来了许多优势,本文将介

随着计算机应用的不断普及和发展,程序设计语言也不断演化和更新。面向对象编程语言在当今程序设计中占据了主导地位,而MySQL则是最流行的关系型数据库管理系统之一。如何在面向对象编程中结合使用MySQL实现更优雅的代码呢?一、面向对象编程的基本概念面向对象编程(ObjectOrientedProgramming,简称OOP)是一种编程思想,它强调对象的概念和

理解PHP面向对象编程中的工厂模式工厂模式是一种常用的设计模式,它用于创建对象的过程中将对象的创建和使用解耦。在PHP面向对象编程中,工厂模式可以帮助我们更好地管理对象的创建和生命周期。本文将通过代码示例来详细介绍PHP中的工厂模式。在PHP中,我们可以通过使用工厂模式来实现对象的创建和初始化过程,而不是直接使用new关键字。这样做的好处是,如果将来需要改变

Java是一种面向对象编程语言,具备三个重要的特性:封装、继承和多态。这三个特性使得Java程序具有高度的可重用性、可维护性和可扩展性。在本文中,我们将介绍Java面向对象编程的三个重要特性。一、封装封装是面向对象编程的基础。它是指将数据和行为封装在一起,保护数据不被直接访问,而是通过类的接口进行访问。封装可以使得程序更加安全、可靠和易于维护。在Java中,

面向对象编程是一种编码设计,它使用数据来表示一组指令。它是一种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。它由描述状态的属性和用来实现对象行为的方法组成,完成了从数据模型到处理模型的结合与统一。

PHP面向对象编程中的访问者模式解析访问者模式是一种常用的设计模式,它可以分离数据结构和处理逻辑,使得同一个数据结构可以有不同的处理逻辑,而且可以在不修改数据结构的情况下增加新的处理逻辑。在PHP中,访问者模式可以帮助我们更好地组织代码,并提高代码的可维护性和可扩展性。本文将深入探讨PHP面向对象编程中的访问者模式,并通过示例代码进行解析。一、模式概述访问者

研究PHP面向对象编程中的适配器模式引言:随着软件系统的复杂度不断提高,面向对象编程在软件开发中扮演着重要的角色。而适配器模式(AdapterPattern)作为常用的设计模式之一,能够解决不兼容接口的问题,提供了一种灵活的扩展机制。本文将详细介绍PHP面向对象编程中的适配器模式,并附上相应的代码示例。一、适配器模式概述适配器模式属于结构型设计模式,通过将


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

WebStorm Mac版
好用的JavaScript开发工具

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

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

Atom编辑器mac版下载
最流行的的开源编辑器