微信公众号

扫码关注官方订阅号

讲师中心
首页
文章
后端开发 web前端 数据库 开发工具 php框架 常见问题 科技 Java 系统教程 电脑教程 硬件教程 手机教程 软件教程 游戏教程 自媒体 新闻
专题
后端开发 web前端 数据库 开发工具 php框架 科技 Java 系统教程 电脑教程 硬件教程 手机教程 软件教程 游戏教程 新闻
AI工具
AI 聊天问答 Agent智能体 AI 文本写作 AI 绘画作图 AI 设计工具 AI 视频创作 AI 音频制作 AI 办公学习 AI 编程开发 Prompt指令
学习
大前端 后端开发 数据库 移动端 运维开发 计算机基础
编程手册
大前端 后端开发 数据库 移动端 运维开发 计算机基础
下载
js特效 网站源码 工具下载 类库下载 网站素材 学习资源 插件扩展 手机/移动开发 手机游戏
搜索
登录/注册
后端开发 web前端 数据库 开发工具 php框架 常见问题 科技 Java 系统教程 电脑教程 硬件教程 手机教程 软件教程 游戏教程
自媒体 新闻
首页 > web前端 > js教程 > 正文

关于js设计模式的超详细介绍

零到壹度
发布: 2018-04-13 17:42:06
原创
1402人浏览过


本篇文章给大家分享的内容是关于js设计模式的超详细介绍,有着一定的参考价值,有需要的朋友可以参考一下

js设计模式

Jan 14, 2017 | 学习笔记 | 3387 Hits


目录

  • 前言

  • 单体模式

  • 工厂模式

  • 迭代器模式

  • 装饰者模式

  • 策略模式

  • 外观模式

  • 代理模式

  • 中介者模式

  • 观察者模式

前言

本文参考于《javascript模式》,因此会大量内容会和书中相同,手上有这本书的朋友可以直接看书。因为我的记忆习惯是抄书,所以我会先抄写下来再发到博客上。

单体模式

单体模式思想在于保证一个特定类仅有一个实例,意味着当你第二次使用同一个类创建信对象时,应得到和第一次创建对象完全相同。

方法一

@@######@@ @@######@@


缺点

instance 属性暴露。

方法二

使用闭包

@@######@@ @@######@@


缺点

因为重写了构造函数,constructor 还是指向了老的构造函数,且实例化后在添加原型属性也是不一样的。如下

@@######@@ @@######@@


方法三

解决方法二问题。

@@######@@


@@######@@


方法四

自运行函数。

@@######@@ @@######@@


工厂模式

工厂模式是为了创建对象。

例子

  • 公共构造函数 CarMaker

  • 名为factory的CarMaker静态方法来创建car对象

@@######@@ @@######@@


实现

@@######@@


@@######@@@@######@@


内置工厂对象

Object() 构造函数即为内置工厂对象。

迭代器模式

有一个包含某种数据集合的对象,该数据可能存储在一个复杂数据结构内部,而要提供一个简单方法讷讷感访问到数据结构中没一个元素。

  • next() 下一个

    创客贴设计
    创客贴设计

    创客贴设计,一款智能在线设计工具,设计不求人,AI助你零基础完成专业设计!

    创客贴设计 51
    查看详情 创客贴设计
  • hasNext() 是否有下一个

  • reWind() 重置指针

  • current() 返回当前

@@######@@


@@######@@


装饰者模式

可以在运行时候添加附加功能到对象中,他的一个方便特征在于其预期行为的可定制和可配置特性。

例子 假设在开发一个销售商品的Web应用,每一笔信销售都是一个人新的 sale 对象。该对象“知道”有关项目的价格,并可以通过 getPrice() 方法返回加个。
根据不同情况,可以用额外的功能装饰此对象。
假设客户在魁北克省,买房需要支付联邦税和魁北克省税,则此时需要调用联邦税装饰者和魁北克省税装饰者。

@@######@@ @@######@@


并且装饰是可选的,例如不再魁北克省有可能没有省税。

方法一

@@######@@ @@######@@


方法二

此方法使用列表实现,而且相对来说比较好理解一点。本质就是把装饰者名称保存到一个列表中并且一次调用此列表中的方法。

@@######@@


@@######@@


策略模式

策略模式支持在运行时候选择算法。例如用在表单验证问题上,可以创建一个具有 validate() 方法的验证器对象,无论表单具体类型是什么,该方法都会被调用,
并且返回结果或者错误信息。

@@######@@


@@######@@


策略模式定义及例子实现参考与《javascript模式》及 汤姆大叔的博客

外观模式

外观模式即让多个方法一起被调用

例如。 stopPropagation() 和 preventDefault() 兼容性一起调用。

@@######@@


@@######@@


代理模式

在代理模式中,一个对象充当另外一个对象的接口,和外观模式区别是:外观模式是合并调用多个方法。
代理模式是介于对象的客户端和对象本身之间,并且对该对象的访问进行保护。

包裹例子

现在有个包裹,卖家要把这个包裹寄给gary,则需要通过快递公司寄过来,此时快递公司就是一个 proxy

@@######@@


@@######@@


论坛权限管理例子

本例子参考与 大熊君

  • 权限列表

    • 发帖 1

    • 帖子审核 2

    • 删帖 3

    • 留言、回复 4

用户 代码 权限
注册用户 001 1 4
论坛管理员 002 2 3 4
系统管理员 003 1 2 3 4
游客 000 null

用户类

@@######@@


@@######@@


论坛类

@@######@@


@@######@@


运行

@@######@@


@@######@@


中介者模式

中介者模式可以让多个对象之间松耦合,并降低维护成本

例如:游戏程序,两名玩家分别给与半分钟时间来竞争决出胜负(谁按键的次数多胜出,这里玩家1按1,玩家2按0)

  • 计分板(scoreboard)

  • 中介者 (mediator)

中介者知道所有其他对象的信息。他与输入设备(此时是键盘)进行通信并处理键盘上的按键时间,之后还将消息通知玩家。玩家玩游戏同时(每一分都更新自己分数)还要
通知中介者他所做的事情。中介者将更新后的分数传达给计分板。

除了中介者莫有对象知道其他对象。

图示

图示

@@######@@


@@######@@


观察者模式

观察者模式在 javascript 中使用非常广泛。所有的浏览器时间就是该模式的实现,node.js中的events也是此模式实现。
此模式另一个名称是 订阅/发布模式 。
设计这种模式原因是促进形成松散耦合,在这种模式中,并不是一个对象调用另一个对象的方法,而是一个对象订阅另一个对象的
特定活动并在状态改编后获得通知。订阅者因此也成为观察者,而被观察的对象成为发布者或者主题。当发生了一个重要事件时候
发布者会通知(调用)所有订阅者并且可能经常已事件对象的形式传递消息。

小结

1.单体模式

针对一个类仅创建一个对象。

2.工厂模式

根据字符串制定类型在运行时创建对象的方法。

3.迭代器模式

提供一个API来遍历或者操作复杂的自定义数据结构。

4.装饰者模式

通过从预定义装饰者对象中添加功能,从而在运行时侯调整对象

5.策略模式

在悬在最佳策略以处理特定任务的时候仍然保持相同的接口。

6.外观模式

通过把常用方法包装到一个新方法中,从来提供一个更为便利的API。

7.代理模式

通过包装一个对象从而控制对它的访问,其中主要方法是将方位聚集为租或者
仅当真正必要时侯才执行访问,从未避免高昂的操作开销。

8.终结者模式

通过是你的对象之间相互不直接“通话”,而是通过一个中介者对子昂进行通信,
从而形成松散耦合。

9.观察者模式

通过创建“可观察”的对象,当发生一个感兴趣的事件时可将改时间通告给所有观察者
从而形成松散耦合。

<br/>
登录后复制
function Universe(){
if(typeof Universe.instance==="object"){
return Universe.instance; //防止被篡改
}
this.xx="xx";
Universe.instance=this;
return this;
}
var uni=new Universe();
var uni2=new Universe();
uni===uni2; //true
登录后复制
<br/>
登录后复制
function Universe(){
var instance=this; //缓存this
this.xx="xx";
Universe=function(){ //重写此构造函数
return instance;
}
}
var uni=new Universe();
var uni2=new Universe();
uni===uni2; //true
登录后复制
<br/>
登录后复制
var uni = new Universe();
Universe.prototype.a = 1
var uni2 = new Universe();
console.log(uni === uni2) //true
console.log(uni.a) //undefinded
console.log(uni2.a) //undefinded
console.log(uni.constructor === Universe); //false
登录后复制
<br/>
登录后复制
function Universe(){
var instance;
Universe=function Universe(){
return instance ;
}
Universe.prototype=this; //保存原型属性
instance=new Universe();
instance.constructor=Universe;
instance.xx="xx";
}
登录后复制
<br/>
登录后复制
var Universe;
(function(){
var instance;
Universe=function Universe(){
if(instance){
return instance;
}
instance=this;
this.xx="xx";
}
})();
var uni = new Universe();
Universe.prototype.a = 1
var uni2 = new Universe();
console.log(uni === uni2) //true
console.log(uni.a)   //1
console.log(uni2.a)  //1
console.log(uni.constructor === Universe);  //true
登录后复制
<br/>
登录后复制
var corolla=CarMaker.factory('compact');
var solstice=CarMaker.factory('convertible');
var cherokee=CarMaker.factory('suv');
corolla.drive() //I have 4 doors
solstice.drive() //I have 2 doors
cherokee.drive() //I have 6 doors
登录后复制
<br/>
登录后复制
<br/>
登录后复制
function CarMaker() {}
CarMaker.prototype.drive = function() {
return "I have " + this.doors + " doors";
}
CarMaker.compact = function() {
this.doors = 4;
}
CarMaker.convertible = function() {
this.doors = 2
}
CarMaker.suv = function() {
this.doors = 6;
}
CarMaker.factory = function(type) {
if (typeof CarMaker[type] !== "function") {
throw "Error"
}
if (typeof CarMaker[type].prototype.drive !== "function") {
CarMaker[type].prototype = new CarMaker();
}
var newCar = new CarMaker[type]();
return newCar;
}
var corolla = CarMaker.factory('compact');
console.log(corolla.drive()); //I have 4 doors
登录后复制
<br/>
登录后复制
var agg = (function() {
var index = 0;
var data = [1, 2, 3, 4, 5, 6];
var length = data.length;
return {
next: function() { //这里是从第一个数据开始输出 本例中为 1
if (!this.hasNext()) {
return null;
}
var element = data[index];
index++;
return element;
},
hasNext: function() {
return index < length;
},
reWind: function() {
index = 0;
},
current: function() {
return data[index];
}
}
})();
while (agg.hasNext()) {
console.log(agg.next()); //1,2,3,4,5,6
}
agg.reWind();  //此时重置指针到0
登录后复制
<br/>
登录后复制
var sale=new Sale(100);
sale=sale.decorate("fedtax"); //联邦税
sale=sale.decorate("quebec"); //魁北克省税
sale=sale.decorate("miney"); //转为美元格式
sale.getPrice(); //返回价格
登录后复制
<br/>
登录后复制
function Sale(price) {
this.price = price;
}
Sale.prototype.getPrice = function() {
return this.price;
};
Sale.decorators = {}; //储存装饰者的对象
//装饰者
Sale.decorators.fedtax = {
getPrice: function() {
var price = this.uber.getPrice();
return price * 0.8; //对price进行处理
},
}
Sale.decorators.quebec = {
getPrice: function() {
var price = this.uber.getPrice();
return price * 0.7; //对price进行处理
},
}
Sale.decorators.money = {
getPrice: function() {
var price = this.uber.getPrice();
return "$" + price * 0.9; //对price进行处理
},
}
/*decorate() 方法
调用装饰者方法 sale.=sale.decorate("fedtax");
fedtax字符串对应 Sale.decorators中的对象属性。新装饰对象 newobj 将继承目前我们所拥有的对象,这就是ixiangthis
为了完成继承部分代码,此时需要一个临时构造函数,先设置 newobj 的 uber 属性,以便于自对象可以访问到父对象。之后从装饰者中
将所有的额外属性复制到新装饰的对象 newobj 中,最后返回 newobj。
*/
Sale.prototype.decorate = function(decorate) {
var F = function() {};
var overrides = this.constructor.decorators[decorate]; //获取装饰者对象
F.prototype = this;
var newobj = new F();
newobj.uber = F.prototype;
for (var key in overrides) {
if (overrides.hasOwnProperty) { //判断对象是不是自身的
newobj[key] = overrides[key];
}
}
return newobj;
};
var sale = new Sale(100);
sale = sale.decorate("fedtax"); //联邦税
sale = sale.decorate("quebec"); //魁北克省税
sale = sale.decorate("money"); //转为美元格式
console.log(sale.getPrice()); //$50.4
登录后复制
<br/>
登录后复制
function Sale(price) {
this.price = price;
this.decorateList = [];
}
Sale.decorators = {};
Sale.decorators.fedtax = {
getPrice: function(price) {
var price = this.uber.getPrice();
return price * 0.8; //对price进行处理
},
}
Sale.decorators.quebec = {
getPrice: function(price) {
var price = this.uber.getPrice();
return price * 0.7; //对price进行处理
},
}
Sale.decorators.money = {
getPrice: function(price) {
var price = this.uber.getPrice();
return "$" + price * 0.9; //对price进行处理
},
}
Sale.prototype.decorate = function(decorator) {
this.decorateList.push(decorator);
};
Sale.prototype.getPrice = function() {
var price = this.price;
this.decorateList.forEach(function(name) {
price = Sale.decorators[name].getPrice(price);
});
return price;
};
var sale = new Sale(100);
sale = sale.decorate("fedtax"); //联邦税
sale = sale.decorate("quebec"); //魁北克省税
sale = sale.decorate("money"); //转为美元格式
console.log(sale.getPrice()); //$50.4
登录后复制
<br/>
登录后复制
var validator = {
// 所有可以的验证规则处理类存放的地方,后面会单独定义
types: {},
// 验证类型所对应的错误消息
messages: [],
// 当然需要使用的验证类型
config: {},
// 暴露的公开验证方法
// 传入的参数是 key => value对
validate: function (data) {
var i, msg, type, checker, result_ok;
// 清空所有的错误信息
this.messages = [];
for (i in data) {
if (data.hasOwnProperty(i)) {
type = this.config[i];  // 根据key查询是否有存在的验证规则
checker = this.types[type]; // 获取验证规则的验证类
if (!type) {
continue; // 如果验证规则不存在,则不处理
}
if (!checker) { // 如果验证规则类不存在,抛出异常
throw {
name: "ValidationError",
message: "No handler to validate type " + type
};
}
result_ok = checker.validate(data[i]); // 使用查到到的单个验证类进行验证
if (!result_ok) {
msg = "Invalid value for *" + i + "*, " + checker.instructions;
this.messages.push(msg);
}
}
}
return this.hasErrors();
},
// helper
hasErrors: function () {
return this.messages.length !== 0;
}
};
//然后剩下的工作,就是定义types里存放的各种验证类了
// 验证给定的值是否不为空
validator.types.isNonEmpty = {
validate: function (value) {
return value !== "";
},
instructions: "传入的值不能为空"
};
// 验证给定的值是否是数字
validator.types.isNumber = {
validate: function (value) {
return !isNaN(value);
},
instructions: "传入的值只能是合法的数字,例如:1, 3.14 or 2010"
};
// 验证给定的值是否只是字母或数字
validator.types.isAlphaNum = {
validate: function (value) {
return !/[^a-z0-9]/i.test(value);
},
instructions: "传入的值只能保护字母和数字,不能包含特殊字符"
};
//使用的时候,我们首先要定义需要验证的数据集合,然后还需要定义每种数据需要验证的规则类型,代码如下:
var data = {
first_name: "Tom",
last_name: "Xu",
age: "unknown",
username: "TomXu"
};
validator.config = {
first_name: 'isNonEmpty',
age: 'isNumber',
username: 'isAlphaNum'
};
//最后获取验证结果 
validator.validate(data);
if (validator.hasErrors()) {
console.log(validator.messages.join("\n"));
}
登录后复制
<br/>
登录后复制
var myEvent = {
stop: function(e) {
if (typeof e.preventDefault() === "function") {
e.preventDefault();
}
if (typeof e.stopPropagation() === "function") {
e.stopPropagation();
}
//for IE
if (typeof e.returnValue === "boolean") {
e.returnValue = false;
}
if (typeof e.cancelBubble === "boolean") {
e.cancelBubble = true;
}
}
}
登录后复制
<br/>
登录后复制
var package = function(receiver) {
this.receiver = receiver;
}
var seller = function(package) {
this.package = package;
this.send = function(gift) {
return package.receiver + "你的包裹:" + gift;
}
}
var express = function(package) {
this.package = package;
this.send = function(packageName) {
return new seller(package).send(packageName);
}
}
//调用
var ems = new express(new package("gary"));
console.log(ems.send("键盘")); //gary你的包裹:键盘
登录后复制
<br/>
登录后复制
function User(name, code) {
this.name = name;
this.code = code;
}
User.prototype.getName = function() {
return this.name;
};
User.prototype.getCode = function() {
return this.code;
};
User.prototype.post = function() {
//发帖功能
};
User.prototype.remove = function() {
// 删帖功能
};
User.prototype.check = function() {
//审核
};
User.prototype.comment = function() {
//留言回复
};
登录后复制
<br/>
登录后复制
function Forum(user) {
this.user=user;
}
Forum.prototype.getUser = function () {
return this.user;
};
Forum.prototype.post = function () {
var code=this.user.getCode();
if(code=="001"||code=="003"){
return this.user.post();
}else{
return false;
}
};
Forum.prototype.remove = function () {
var code=this.user.getCode();
if(code=="002"||code=="003"){
return this.user.remove();
}else{
return false;
}
};
Forum.prototype.check = function () {
var code=this.user.getCode();
if(code=="002"||code=="003"){
return this.user.check();
}else{
return false;
}
};
Forum.prototype.comment = function () {
var code=this.user.getCode();
if(code=="001"||code=="002"||code=="003"){
return this.user.comment();
}else{
return false;
}
};
登录后复制
<br/>
登录后复制
new Forum(new User("administartor","003"));
登录后复制
<br/>
登录后复制
function Player(name) {
this.points = 0;
this.name = name;
}
Player.prototype.play = function() {
this.points += 1;
mediator.played();
};
var scoreboard = {
element: "这里是获取的element用于展示分数",
update: function(score) { //更新分数
var msg;
for (var key in score) {
if (score.hasOwnProperty(key)) {
msg += score[key];
}
}
this.element.innerText = msg;
},
}
var mediator = {
players: {}, //玩家对象
setup: function() {
var players = this.players;
players.home = new Player("home");
players.guest = new Player('guest');
},
played: function() {
var players = this.players;
var score = {
home: players.home.points,
guest: players.guest.points
}
},
keypress: function(e) {
e = e || window.event;
if (e.which === 49) { //or keycode   对应按键 1
mediator.players.home.play();
return;
}
if (e.which === 48) { // 对应按键 0
mediator.player.guest.play();
return;
}
},
}
//运行
mediator.setup();
window.onkeypress = mediator.keypress;
setTimeout(function() { //设置30秒游戏时间
window.onkeypress = null;
alert("game end");
}, 30000);
登录后复制

以上就是关于js设计模式的超详细介绍的详细内容,更多请关注php中文网其它相关文章!

相关标签:
javascript

大家都在看:

优化数组循环:PHP/JavaScript中for循环的最佳实践 JavaScript函数中循环累加的陷阱:理解return语句的作用 解决JavaScript函数中循环过早返回的问题 掌握JavaScript函数中循环与return语句的正确用法 PHP与JavaScript数组循环中的性能与可读性优化实践
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
收藏 点赞
上一篇:JS怎么判断客户端类型 下一篇:一些关于js的实用小算法
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
  • 跟我学PS第八天02:光效素材的抠图方法
    2018-08-28 15:02:42
  • 跟我学PS第八天01:如何抠取文件中的印章
    2018-08-25 10:55:46
  • 跟我学PS第七天02:如何抠出复杂树林
    2018-08-20 16:25:41
  • 跟我学PS第七天01:如何将彩图抠出线稿效果
    2018-08-18 11:26:54
  • 跟我学PS第六天02:模糊工具
    2018-08-14 16:35:58
  • 跟我学PS第六天01:修复画笔工具
    2018-07-28 15:36:43
  • 跟我学PS第五天02:移动工具的使用方法和应用
    2018-07-27 16:59:00
  • 跟我学PS第五天01:使用裁剪工具
    2018-07-27 15:22:47
  • 跟我学PS第四天02:练习Photoshop中的套索工具
    2018-07-23 17:56:00
  • 跟我学PS第四天01:如何给照片加边框效果
    2018-07-23 16:21:38
最新问题
js中this的六种模式 this的指向取决于函数调用方式,共六种绑定模式:1.全局环境中this指向window(浏览器)或global(Node.js);2.独立调用时非严格模式指向全局对象,严格模式为undefined;3.作为对象方法调用时this指向调用者;4.构造函数中this指向新创建的实例;5.显式绑定通过call、apply、bind指定this值;6.箭头函数的this继承外层作用域,不可被显式改变。关键在于调用方式而非定义位置。
2025-11-10 16:17:02
695
可靠的AWS SDK JS S3请求超时处理策略 AWSSDKforJavaScript在处理S3操作时,其内置的httpOptions.timeout可能表现出不一致性,导致请求超时设置失效或长时间挂起。本文将介绍一种更稳健的解决方案,通过结合使用AWSSDK请求对象的abort()方法与JavaScript的setTimeout函数,实现对S3请求的精确和可预测的超时控制,从而有效避免资源浪费和应用程序阻塞。
2025-11-10 16:14:25
670
React/JSX与TypeScript:解决自定义HTML标签的类型声明问题 本文详细介绍了在React/JSX项目中使用自定义HTML标签(如SliderRevolution的rs-fullwidth-wrap)时,如何解决TypeScript报告的类型错误。通过讲解declareglobal和namespaceJSX的正确用法,并提供具体代码示例,指导开发者如何为非标准DOM元素扩展JSX.IntrinsicElements接口,从而确保代码的类型安全和编译通过。
2025-11-10 16:14:03
889
自定义工具栏在全屏模式下不显示按钮的解决方案 在使用自定义工具栏并启用全屏功能时,开发者可能会遇到工具栏在进入全屏模式后消失的问题,导致无法退出全屏。本文将深入探讨这一常见UI挑战,并提供两种有效的解决方案:一是通过调整HTML结构,移除可能导致冲突的特定属性和元素;二是通过CSS样式覆盖,利用position和高z-index值确保工具栏在全屏状态下依然可见,从而恢复其功能性。
2025-11-10 16:07:02
342
JavaScript 箭头函数:this 绑定与使用场景 箭头函数的this绑定取决于定义时的上下文且不可更改,适合用于数组方法回调、异步操作和工具函数,但不应用于对象方法、事件处理或构造函数,以避免this指向错误。
2025-11-10 16:07:04
809
React组件重复渲染、Key警告与数据获取优化实践 本文旨在解决React组件在数据获取和列表渲染中常见的重复渲染、keyprop警告问题。通过深入探讨useEffect的执行机制,我们将学习如何实施条件性数据加载以避免不必要的API请求,并强调keyprop在优化列表性能和避免错误中的核心作用,确保组件的高效稳定运行。
2025-11-10 15:58:02
151
Puppeteer 自动化:可靠点击动态页面元素的策略 在使用Puppeteer进行网页自动化时,开发者常遇到因页面元素类名动态变化而导致的点击失效问题。本文旨在提供一套健壮的解决方案,通过采用更通用的元素选择器和在页面上下文中执行点击操作,有效克服这类挑战。我们将探讨如何识别稳定属性、利用page.evaluate()模拟原生点击,并结合最佳实践确保自动化脚本的稳定性和可靠性,从而提升Puppeteer脚本的适应性。
2025-11-10 15:47:01
773
PHP 表单提交:解决 $_POST 无法获取按钮点击事件的常见问题 本教程旨在解决PHP开发中$_POST无法正确接收表单提交数据,特别是按钮点击事件的问题。文章深入分析了这一常见现象的根本原因——HTML表单结构缺失,并提供了详细的解决方案。通过构建正确的结构,确保所有相关输入元素和提交按钮被包含在内,从而使PHP后端能够成功捕获并处理用户提交的数据,实现预期的业务逻辑。
2025-11-10 15:43:01
486
TypeScript在大型JavaScript项目中的类型系统设计 TypeScript类型系统提升大型项目可维护性与安全性,需明确模块边界、使用泛型增强复用性、实施严格检查并渐进迁移,保持类型一致实用。
2025-11-10 15:42:03
372
在WordPress菜单中实现链接定向到指定iframe的教程 本教程详细介绍了如何在WordPress中,通过自定义代码将菜单项链接的目标(target)属性设置为指定的iframe名称,而非默认的_blank。文章将指导您修改functions.php文件以应用nav_menu_link_attributes过滤器,并强调确保目标iframe在页面中正确存在且其name属性与链接目标匹配的关键步骤,从而实现菜单链接在特定iframe中打开。
2025-11-10 15:37:01
337
相关专题
更多>
  • python除法运算符
  • python 平方
  • python 怎么安装库
  • python中不等于怎么写
  • python输入根号教程
  • 学python所需软件推荐
  • python 一个列表 相关教程大全
  • python内置函数大全
热门推荐
  • 在Rails应用中高效安全地将数据库数据传递给JavaScript
  • JavaScript碰撞检测算法
  • 全栈项目怎么优化加载速度_全栈JavaScript项目性能优化与加载提速方法
  • JavaScript中HTML内容字符精确统计:兼顾换行符的实现策略
  • 前端埋点与数据上报的JavaScript实现_js数据分析
开源免费商场系统广告
热门教程
更多>
相关推荐
热门推荐
最新课程
  • JavaScript
    JavaScript
    79064次学习
    收藏
  • JavaScript教程
    JavaScript教程
    119521次学习
    收藏
  • JavaScript 参考手册
    JavaScript 参考手册
    291174次学习
    收藏
  • JavaScript ES5基础线上课程教学
    JavaScript ES5基础线上课程教学
    64937次学习
    收藏
  • 最新ThinkPHP 5.1全球首发视频教程(60天成就PHP大牛线上培训班课)
    最新ThinkPHP 5.1全球首发视频教程(60天成就PHP大牛线上培训班课)
    1484960次学习
    收藏
  • phpStudy极速入门视频教程
    phpStudy极速入门视频教程
    529754次学习
    收藏
  • 独孤九贱(4)_PHP视频教程
    独孤九贱(4)_PHP视频教程
    1249519次学习
    收藏
  • PHP实战天龙八部之仿爱奇艺电影网站
    PHP实战天龙八部之仿爱奇艺电影网站
    769630次学习
    收藏
  • 最新Python教程 从入门到精通
    最新Python教程 从入门到精通
    2726次学习
    收藏
  • JavaScript ES5基础线上课程教学
    JavaScript ES5基础线上课程教学
    64937次学习
    收藏
  • PHP新手语法线上课程教学
    PHP新手语法线上课程教学
    6428次学习
    收藏
  • 支付宝沙箱支付(个人也能用的支付)
    支付宝沙箱支付(个人也能用的支付)
    4508次学习
    收藏
  • 麻省理工大佬Python课程
    麻省理工大佬Python课程
    41271次学习
    收藏
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
  • [表单按钮] jQuery企业留言表单联系代码
  • [播放器特效] HTML5 MP3音乐盒播放特效
  • [菜单导航] HTML5炫酷粒子动画导航菜单特效
  • [表单按钮] jQuery可视化表单拖拽编辑代码
  • [播放器特效] VUE.JS仿酷狗音乐播放器代码
  • [html5特效] 经典html5推箱子小游戏
  • [图片特效] jQuery滚动添加或减少图片特效
  • [相册特效] CSS3个人相册封面悬停放大特效
  • [企业站源码] Psky企业网站系统1.1.2
  • [电商源码] SeoShop
  • [企业站源码] 玻璃钢企业网站源码1.5
  • [电商源码] 小米绿色生鲜商城电脑手机微信商城三合一
  • [企业站源码] 艺帆网络工作室网站源码1.7.5
  • [电商源码] 开源(网店)电子商务软件iWebShop
  • [企业站源码] 绿色水果蔬菜响应式网站模板1.0
  • [电商源码] 影缘版黄页系统
  • [网站素材] 秋季枫叶手绘标签合集矢量素材
  • [网站素材] 极简剪影中国城市地标矢量素材
  • [网站素材] 线稿风实验室器材合集矢量素材
  • [网站素材] 线稿风格商务办公矢量图标合集
  • [网站素材] 商务办公图标设计矢量素材
  • [网站素材] 创意咖啡糕点美食店海报PSD素材下载
  • [网站素材] 化学实验室器材矢量背景
  • [网站素材] 手绘咖啡器具插图矢量素材
  • [前端模板] 驾照考试驾校HTML5网站模板
  • [前端模板] 驾照培训服务机构宣传网站模板
  • [前端模板] HTML5房地产公司宣传网站模板
  • [前端模板] 新鲜有机肉类宣传网站模板
  • [前端模板] 响应式天气预报宣传网站模板
  • [前端模板] 房屋建筑维修公司网站CSS模板
  • [前端模板] 响应式志愿者服务网站模板
  • [前端模板] 创意T恤打印店网站HTML5模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号

微信扫码
关注PHP中文网服务号

技术交流群

QQ扫码
加入技术交流群

PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • PHP学习

  • 技术支持

  • 返回顶部