当前位置: 首页 > news >正文

犀牛云网站建设特点做一个网站最低多少钱

犀牛云网站建设特点,做一个网站最低多少钱,wordpress 安装 白屏,做机械的老板都看什么网站工厂模式 工厂模式 是用来创建对象的一种最常用的设计模式。工厂模式不暴露创建对象的具体逻辑,而是将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂。工厂模式常见于大型项目,例如 jQuery 的 $ 对象,我们创建选择器对…

工厂模式

工厂模式 是用来创建对象的一种最常用的设计模式。工厂模式不暴露创建对象的具体逻辑,而是将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂。工厂模式常见于大型项目,例如 jQuery 的 $ 对象,我们创建选择器对象之所以没有 new selector 就是因为 $() 已经是一个工厂方法,其他例子例如 React.createElement()Vue.component() 都是工厂模式的实现。

工厂模式根据抽象程度的不同可以分为三种:

  • 简单工厂:通过第三方的类完成松耦合的任务
  • 复杂工厂:通过把实例化的任务交给子类来完成的,用以到达松耦合的目的
  • 超级工厂:通过 eval() 来完成智能工厂

工厂的目的:在于判断接口最终用哪个类实例化(故与接口密不可分)。

使用工厂最终达到的效果是:多态,和类与类之间的松耦合。

应用场景

ES5 实现工厂模式

function createPerson(name, age, job) {let person = new Object();person.name = name;person.age = age;person.job = job;person.sayNam = function () {console.log(`I'm ${name}`);};return person;
}const person1 = createPerson('Ben', 21, 'student');
const person2 = createPerson('Gray', 25, 'Doctor');

函数 createPerson() 能够根据接受的参数来构建一个包含所有必要信息的 Person 对象。可以无数次调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象。工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。

ES6 实现工厂模式

class User {constructor(name, auth) {this.name = name;this.auth = auth;}
}
class UserFactory {static createUser(name, auth) {//工厂内部封装了创建对象的逻辑://权限为 admin 时,auth=1;权限为 user 时,auth 为 2//使用者在外部创建对象时,不需要知道各个权限对应哪个字段, 不需要知道赋权的逻辑,只需要知道创建了一个管理员和用户if (auth === 'admin') return new User(name, 1);if (auth === 'user') return new User(name, 2);}
}
const admin = UserFactory.createUser('cxk', 'admin');
const user = UserFactory.createUser('xz', 'user');

原型模式

我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由 特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么 prototype 就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

function Person(){}Person.prototype.name = 'Uzi';
Person.prototype.age = 22;
Person.prototype.job = 'E-Sports Player';
Person.prototype.sayName = function(){console.log(this.name);
}const uzi1 = new Person();
uzi1.sayName();
// 'Uzi'const uzi2 = new Person();
uzi2.sayName();
// 'Uzi'// 共用公用方法
console.log(person1.sayName == person2.sayName);
// true

与构造函数不同,新对象的这些属性和方法是由所有实例共享的。

理解原型对象

无论什么时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个 prototype 属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个 constructor(构造函数)属性,这个属性是一个指向 prototype 属性所在函数的指针。

创建了自定义的构造函数之后,其原型对象默认只会取得 constructor 属性;至于其他方法,则都是从 Object 继承而来的。当调用构造函数创建一个新的实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMAScript 5 中管这个指针叫做 [[Prototype]]。虽然在脚本中没有标准的方式访问 [[Prototype]],但 Firefox、Safari 和 Chrome 在每个对象上都支持一个属性 __proto__;而在其他实现中,这个属性对脚本则是完全不可见的。不过,要明确的真正重要的一点就是,这个连接存在于实例与构造函数的原型之间,而不是存在于实例与构造函数之间。

原型最初只包含 constructor 属性,而该属性也是共享的,因此可以通过对象实例访问。

虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,而该属性与实例原型中的一个属性同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的属性。

function Person(){}Person.prototype.name = 'Nicholas';
Person.prototype.age = 29;
Person.prototype.job = 'Software Engineer';
Person.prototype.sayName = function(){
console.log(this.name);
};const person1 = new Person();
const person2 = new Person();person1.name = 'Greg';
console.log(person1.name);
// 'Greg' 		// from instance
console.log(person2.name);
// 'Nicholas' 	// from prototype

两个实例访问 name 属性的过程:

  • person1 ==> 实例中读取 name 属性 ==> 在实例中读取 name 属性成功
  • person2 ==> 实例中读取 name 属性 ==> 实例中无 name 属性 ==> 从原型链中读取 name 属性 ==> 读取成功

当为对象实例添加一个属性时,这个属性就会 屏蔽 原型对象中保存的同名属性。换句话说,添加这个属性只会阻止我们访问原型中的那个属性值,但不会修改那个属性。即使这个属性设置为 null,也只会在实例中设置这个属性,而不会恢复其指向原型的连接。不过,使用 delete 操作符则可以完全删除实例属性,从而让我们能够重新访问原型中的属性。

ECMAScript5 的 Object.getOwnPropertyDescriptor() 方法只能用于实例属性,要取得原型属性的描述符,必须直接在原型对象上调用 Object.getOwnPropertyDescriptor() 方法。

原型与实例属性检测

有两种方式使用 in 操作符:单独使用和在 for-in 循环中使用。在单独使用时,in 操作符会在通过对象能够访问给定属性时返回 true无论该属性存在于实例中还是原型中

同时使用 hasOwnProperty() 方法和 in 操作符,就可以确定该属性到底是存在于对象中,还是存在于原型中。

由于 in 操作符只要通过对象能够访问到属性就返回 truehasOwnProperty() 只在属性存在于实例中时才返回 true,因此只要 in 操作符返回 truehasOwnProperty() 返回 false,就可以确定属性是原型中的属性。

更简单的原型语法

前面的例子中每添加一个属性和方法就要输入一遍 Person.prototype,为减少不必要的输入,也为了从视觉上更好地封装原型的功能,更常见的做法是用一个包含所有属性和方法的对象字面量来重写整个原型对象。

function Person(){}Person.prototype = {name: 'Nicholas',age: 29,job: 'Software Engineer',sayName: function (){console.log(this.name);}
}

前面介绍过,没创建一个函数,就会同时创建它的原型对象,这个对象自动获得构造函数。而这里的语法,这里相当于重写了实例的原型对象,相应地原型对象中的构造函数 constructor 亦被覆盖,不再指向 Person 函数。此时,尽管 instanceof 操作符还能返回正确的结果,但通过 constructor 已经无法确定对象的类型了。

当然,我们可以手动为它设置回适当的值。但是,以这种方式重设 constructor 属性回导致它的 [[Enumerable]] 特性被设置为 true。默认情况下,原生的 constructor 属性是不可枚举的。

function Person(){}Person.prototype = {constructor: Person,name: 'Nicholas',age: 29,job: 'Software Engineer',sayName: function (){console.log(this.name);}
}

重设构造函数,只适用于 ECMAScript5 兼容的浏览器。

Object.defineProperty(Person, 'constructor', {enumerable: false,value: Person
})

原型的动态性

由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来,即使是先创建了实例后修改原型也照样如此。

实例与原型之间的关系是松散的,

function Person(){}const friend = new Person();Person.prototype = {constructor: Person,name: 'Nicholas',age: 29,job: 'Software Engineer',sayName: function (){console.log(this.name);}
};friend.sayName();
// error

重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系,它们引用的仍然是最初的原型。

原型对象的原型

原型模式的重要性不仅体现在创建自定义类型方面,就连所有原生的引用类型,都是采用这种模式创建的。所有原生引用类型(Object、Array、String 等等)都在其构造函数的原型上定义了方法。

通过原生对象的原型,不仅可以取得所有默认方法的引用,而且也可以定义新方法。可以像修改自定义对象的原型一样修改原生对象的原型,因此可以随时添加方法。

尽管可以这样做,但我们不推荐在产品化的程序中修改原生对象的原型。如果因某个实现中缺少某个方法,就在原生对象的原型中添加这个方法,那么当在另一个支持该方法的实现中运行代码时,就可能会导致命名冲突。而且,这样做也可能会意外地重写原生方法。

原型对象的问题

原型模式省略了为构造函数传递初始参数的环节,结果所有实例在默认情况下都将取得相同的属性值。

原型中的所有属性是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒也说得过去,毕竟,通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。然而,对于包含引用类型值的属性来说,问题就比较突出了。

function Person(){}Person.prototype = {name: 'Nicholas',age: 29,job: 'Software Engineer',friends: ['Shelby', 'Court'],sayName: function (){console.log(this.name);}
}const person1 = new Person();
const person2 = new Person();person1.friends.push('Van');console.log(person1.friends);
// 'Shelby,Court,Van'
console.log(person2.friends);
// 'Shelby,COurt,Van'
console.log(person1.friends == person2.friends);
// true
http://www.yayakq.cn/news/76382/

相关文章:

  • 免费外贸自建站wordpress模板导入
  • 网站中常用的英文字体动漫设计是什么
  • 凡科网站建设样品图江门17年seo优化技术软件
  • 网站一个月wordpress底部加上自己的版权信息
  • 免费网站申请域名com做设计图的网站
  • 商城网站建设公司电话tpshop开源商城
  • 网站建设百度索引上海十大网站排名
  • 在哪个网站上可以找兼职做短网址短链接生成器
  • 肇庆网站建设维护武威做网站的公司
  • 精湛的网站设计国内空间设计公司
  • 怎么做赛事直播网站网站优化推广公司排名
  • 西宁做网站的公司捌君博力请做纪录片卖给视频网站
  • 石家庄网站制作工具求个网站你懂我意思是
  • 免费图片素材网站有哪些招聘运营专员
  • 福建网站建设价格几分钟做网站
  • 外网网站有什么好的推荐哪个网站可以悬赏做图
  • 东莞网站建设五金建材电子商务网站建设期末试卷答案
  • 佛山市城乡住房建设局网站重庆企业网站开发
  • 域名商的网站建设网银登录网站
  • 专题定制网站建设html5的静态壁纸
  • 电子商务网站建设规划的内容wordpress 插件新页面
  • 单位网站建设收费标准网络营销包括的主要内容有
  • 青岛网站建设加王道下拉怎么把网站做成手机版的
  • 建设网站的成本有哪些前端学习网站建设教程
  • 网站建设怎么分析市场分析网站被k 但收录内页
  • 网站优化改动怎么做苏州建网站公司
  • 如何在国外网站做免费推广微信小程序功能开发
  • 衡阳建设学校网站网站的基础知识
  • 网站建设与管理试题及答案黑料社2023
  • ui下载高清素材的网站有哪些wordpress搬家换域名