编写可维护的JavaScript-编程实践

2023-05-16

UI层的松耦合

1.将JavaScript从css中抽离出来;现在大部分已经不支持;
2. 将css从JavaScript中抽离出来。

不要直接在js内添加样式;如:e.style.color="red";
可以使用更改类名的方式来动态的修改样式。如:e.className=”css”
javascript不应直接操作样式,以便保持和css的松耦合。

3.将JavaScript从Html中抽离。
不要再写<h2 onclick="login()">登陆账号</h2>;这样的函数体了。这是2000年左右的写法。

4.将Html从JavaScript中抽离。

渲染html的时候,总会插入一些html结构;如

    var myDiv=document.querySelector("#mydiv");
    myDiv.innerHTML="<h2>登陆成功</h2>";

缺点:
1.增加了文本和结构性的负责度。先在dom树中查找,然后再页面的html中比较不同。如果发生bug追中bug就成一件艰难的事了。
2.相比修改JavaScript代码,修改标签通常不会引起太多错误。
解决的办法:
1.从服务器加载。
就是向服务器发起请求获取字符串。
2.简单客户端模板。
放入script中:

<script type="text/x-handlebars-template" id="myTemp">
    <li><a href="#">我关注的品牌</a></li>
</script>

然后通过script标签的text属性来提取模板文本。

    var myTemp=document.querySelector("#myTemp");
    var tempText=myTemp.text;
    //插入指定的位置
    document.querySelector("#myList").innerHTML=tempText;

3.复杂的客户端模板
可以使用一些流行的模板引擎来实现,如artTemplate.js

避免使用全局变量

由于一些简单的书写错误,可能造成对全局变量的修改。如:

function getData() {
    var foo=10;
    color="red";
    return color;
}

这里一不小心就把全局变量color修改了。
同时每个全局变量,每次查找的时候都会影响性能,;

单全局变量方式 ##

依赖尽可能少的全局变量,即只创建一个全局变量。这个唯一全局对象名是独一无二 的,不会和内置API产生冲突,并将你所有的功能代码都挂载到这个全局对象上。因此每个可能的全局变量都成为你唯一全局对象的属性,从而不会创建多个全局变量。如:

var MainPerson={};
MainPerson.People=function (title) {
    this.title=title;
    this.logo="I am the SuperMan"
}
MainPerson.People.prototype.sayHi=function (move) {
    var str="when in the " + this.title+" I will say"+this.logo;
    str+=" "+move;
    console.log(str);
}
var tom=new MainPerson.People("afternoon");
tom.sayHi("run")

MainPerson.jack=new MainPerson.People("morning");
MainPerson.jack.sayHi("go go go");

//when in the afternoon I will sayI am the SuperMan run
//when in the morning I will sayI am the SuperMan go go go

上面的例子我们可以看到只有一个全局变量MainPerson,其他的任何信息都挂载到这个对象上。很容易让整个团队的人为它添加属性,避免全局污染。

命名空间

在JavaScript中,你可以使用对象轻而易举的创建自己的命名空间。一般有两条约定:

var MyBooks={};
//表示一个新的命名空间
MyBooks.WestStory={};

1.每个文件中都创建新的全局对象来声明自己的命名空间。如上面的例子。
2.每个文件都需要给一个命名空间挂载对象。—-在这种情况下,你需要首先保证这个命名空间是已经存在的,这时全局对象非破坏性的处理命名空间的方式变得非常有用,如下面代码所示:

var YourGlobal={
    namespace:function (ns) {
        var parts=ns.split("."),
            obj=this,
            i,len;
        for(i=0,len=parts.length;i<len;i++){
            if(!obj[parts[i]]){  //新的命名空间
                obj[parts[i]]={};
            }
            obj=obj[parts[i]];  //将已经的存在的绑定到YourGlobal上。
        }
        return obj;
    },
}
//同时创建了"YourGlobal.MainPerson.People""YourGlobal.People";
//因为之前没有创建过他们,因此每个都是全新创建的。
YourGlobal.namespace("MainPerson.People");
console.log(YourGlobal.MainPerson.People);
console.log(YourGlobal);

结果:

这里写图片描述

现在你可以使用这个命名空间;

YourGlobal.MainPerson.People.name="jack"; 
console.log(YourGlobal.MainPerson.People); //{name: "jack"}

他不会操作YourGlobal.MainPerson本身;同时会保持YourGlobal.MainPerson.People原封不动。如下

YourGlobal.namespace("MainPerson.People");
基于你的单全局对象使用`namespace()`方法可以让开发者放心的认为命名空间总是存在的。这样每个文件都可以首先调用`namespace()`来声明开发者将要使用的命名空间,这样做不会对已经有的命名空间造成任何破坏,这个方法可以让开发者解放出来,在使用命名空间之前不必再去判断它是否存在。 

模块

要使用AMD模块,必须需要一个模块加载器,可以使用Require.js 模块加载器来加载AMD模块。其中jQuery,Yui也有其合适的方法。 具体的详细的方法请自行查找文档。
异步模块定义(AMD)
AMD模块,可以你指定的模块名称、依赖、和一个工厂方法,依赖加载完成后执行这个工厂方法。这些内容全部作为参数传入一个全局函数define()中,其中第一个参数是模块名称;然后是依赖列表,最后是工厂方法。他的每一个依赖都会对应到独立的参数传入工厂方法里,比如:

define("module-name", ["dependency1", "dependency2"], 
    function (dependency1, dependency2) {
    //模块正文
}) 

可以返回他的公共接口

define("people", ["dependency1", "dependency2"], function (dependency1, dependency2) {
    //模块正文
    var MainPerson = {};
    MainPerson.People = function (title) {
        this.title = title;
        this.logo = "I am the SuperMan"
    }
    return MainPerson;
})

零全局变量

情形:一段不会被其他脚本访问到的完全独立的脚本。之所以存在这种情形,是因为所有所需的脚本都会合并到一个文件,或者因为这段非常短小且不提供任何接口的代码会被插入至一个页面中。如下:

(function (win) {
    var doc=win.document;
    //定义其他的变量

    //执行其他的相关的代码
    console.log(doc.querySelectorAll("div"));

})(window)

这段立即执行的代码传入了window对象,因此这段代码不需要直接引用任何全局变量。在这个函数内部,变量doc是指向document对象的引用,只要是函数的代码中没有直接修改window或doc且所有变量都是var关键字来定义,这段脚本则可以注入到页面中而不会产生任何全局变量。
这种模式的使用场景有限:只要你的代码需要被其他的代码所依赖,就不能使用这种零全局变量的方式,如果你的代码需要在运行时被不断扩展或修改也不能使用零全局变量的方式,但是,如果你的脚本非常短,且不需要和其他代码产生交互,可以考虑使用零全局变量的方式实现代码。

事件处理

如下面的代码:

//不好的写法
function move(e) {
    console.log(e);
}
addListener(document.querySelector("#abc"),"click",move);

function addListener(target,type,handler) {
    if(target.addEventListener){
        target.addEventListener(type,handler);
    }else if(target.attachEvent){
        target.attachEvent("on"+type,handler);
    }else {
        target["on"+type]=handler;
    }
}

虽然这段代码看起来非常简单且没有什么问题,但实际上是不好的写法,因为这种做法有其局限性。

典型用法

规则一: 隔离应用逻辑

将应用逻辑从所有事件处理程序中抽离出来的做法是一种最佳的实践,因为不知道什么时候会用到同一逻辑;
影响测试:测试时需要直接触发功能代码,而不必通过模拟对元素的点击来触发。如果这样将应用逻辑放置于事件处理程序中,唯一的测试方法是制造事件的触发。尽管某些测试框架可以模拟触发事件,但实际上这不是测试的最佳方法。调用功能性代码最好的做法就是单个函数调用。

//好的写法
var MyApp={
    move:function (e) {
        console.log(e.target.innerText);
        var popup=document.querySelector("#popup");
        popup.style.left=e.clientX+"px";
        popup.style.top=e.clientY+"px";
        popup.className="popup";
    },
    handleClick:function (e) {
        this.move(e);
    },

}
addListener(document.querySelector("#abc"),"click",function (e) {
    MyApp.handleClick(e)
});

这里的事件处理程序的逻辑都转移到MyApp.move中;

规则二: 不要分发事件对象
上面的还有一个问题,即event对象被无节制的分发。他从匿名事件处理函数传入了MyApp.handleClick(),然后又传入了MyApp.move;而实际中,event对象上包含很多和事件相关的信息,而实际中只用几个;
最佳的办法是让事件处理程序使用event对象来处理事件,然后拿到所有需要的数据传给应用逻辑。如上面的只需要x和y两个坐标。

var MyApp={
    move:function (x,y) {
        var popup=document.querySelector("#popup");
        popup.style.left=x+"px";
        popup.style.top=y+"px";
        popup.className="popup";
    },
    handleClick:function (e) {
        this.move(e.clientX,e.clientY);
    },
}
addListener(document.querySelector("#abc"),"click",function (e) {
    MyApp.handleClick(e)
});

重写之后,仅仅将x,y的值传入MyApp.move;可以很清晰的对这段代码进行测试。

//可以这样测试
MyApp.move1010

当处理事件时,最好让事件处理程序成为接触到event对象的唯一函数。事件处理程序应当在进入应用逻辑之前针对event对象执行任何必要的操作,包括默认事件或阻止事件冒泡,都应当直接包含在事件处理程序中。

var MyApp={
    move:function (x,y) {
        var popup=document.querySelector("#popup");
        popup.style.left=x+"px";
        popup.style.top=y+"px";
        popup.className="popup";
    },
    handleClick:function (e) {
        e.preventDefault();
        e.stopPropagation();
        this.move(e.clientX,e.clientY);
    },
}
addListener(document.querySelector("#abc"),"click",function (e) {
    MyApp.handleClick(e)
});

避免“空比较”

检测原始值:typeof

可以对比出5中原始类型:字符串(“string”),数字(“number”),布尔值(“boolean”),null和undefined ;
typeof variable= typeof(variable)

检测引用值:instanceof

使用typeof 检测null ;返回“object”;这是很严重的bug;所以又引入了instanceof;语法:
value instanceof constructor;

var now=new Date();
console.log((now instanceof Object));  //true
console.log((now instanceof Date));    //true

对于函数和数组;这两个类型来说,一般用不到instanceof

检测函数

检测函数的最好使用typeof,直接返回function

检测数组

一个新的检测方式

Object.prototype.toString.call(value) //"[object ***]"

console.log(Object.prototype.toString.call(now));//[object Date]

检测属性

当检测一个属性是否在对象存在时:
此时不要与空值(null,undefined)进行比较;这样的话,就是通过给定的名字来检查属性的值。如:

//不好写法
if(obj[propertyname]){
    //执行代码
}

if(obj[propertyname]!=null){
    //执行代码
}
if(obj[propertyname]!=undefined){
    //执行代码
}

而非判断给定的名字所指的属性是否存在,当其属性的值为0,“ ”,false,null和undefined时,上面的做法就不合适了。
所以最好的方法使用in运算。其仅仅简单的判断属性是否存在,而不会去读属性值。如果实例对象的属性存在、或者继承自对象的原型,in运算符都会返回true。如:

var obj={
    num:0,
    content:null,
}
if("content" in obj){
    //执行
    console.log(obj["content"]);//null
}
if(obj["content"]){
    //不执行
    console.log(obj["content"]);
}
if("num" in obj){
    //执行
    console.log(obj["num"]);//0
}
if(obj["num"]){
    //不执行
    console.log(obj["num"]);
}

还有一个检查实例对象某个属性存在的方法是hasOwnProperty()。所有继承自Object和JavaScript对象都有这个方法,如果实例中存在这个属性则返回true,(如果这个属性只存在原型里,则返回false)。

if(obj.hasOwnProperty("num")){
    console.log((obj.hasOwnProperty("num")));//true
    console.log(obj["num"]);//0
}

区别:in操作符只要通过对象能访问到属性就返回true。hasOwnProperty()只在属性存在于实例中时才返回true。用“In”来查找是深度查找 查找原型链里 是否有这……属性。 而平时小项目常用“hasOwnProperty”来查找(查找自身小范围内是否有此属性,可能更快捷高效。而“in”有特殊需求时使用。);in判断的是对象的所有属性,包括对象实例及其原型的属性;
而hasOwnProperty则是判断对象实例的是否具有某个属性。

将配置数据从代码中分离出来

配置数据

配置数据就是应用中写死的值。例如

  • URL
  • 需要展现给用户的字符串
  • 重复的值
  • 设置(比如每页的配置项)
  • 任何可能发生变更的值。

抽离配置数据

将配置数据拿到外部,从JavaScript代码中拿掉。单独放入一个文件中。

保存配置数据

配置数据最好放在单独的文件中,以便清晰的分隔数据和应用逻辑。格式的话,就是现在像大家目前所知的JSON格式。或者放入js文件中,建立一个名为config的对象。例子:

var config={"URL_INVAILD":"/errors/invaild.php","INVAILD_VALUE":"INVAILD value"}

抛出自定义错误

在JavaScript中抛出错误

throw new Error("something bad");

这里写图片描述
如果你这样写:throw "something bad";这样确实能抛出一个错误;但是火狐、欧朋、谷歌则会显示Uncaught something bad的错误;而且,可以抛出任何类型的数据。
注意:如果没有通过try-catch语句捕获,抛出任何值都将引发一个错误。因此为了针对所有的浏览器,唯一不出错的显示自定义的错误消息的方式就是用一个Error对象。

抛出错误的好处 ##

function getDivs(e) {
    if(e&&e.getElementsByTagName){
        return e.getElementsByTagName("div");
    }else {
        throw new Error("getDivs():参数必须是一个DOM元素");
    }
}

抛出自己的错误可以帮助自己快速帮助自己调试问题。最好在错误信息中包含函数名称+函数失败的原因。

何时抛出错误

不要抛出每一个错误,那样会对脚本的整体性能造成影响;只需抛出关键错误。

  • 一旦修复了一个很难调试的错误,尝试增加一两个自定义错误。当再次发生错误时,这将有助于更容易的解决问题。
  • 如果正在编写代码,思考一下:“我希望【某些事情】不会发生,如果发生,我的代码会一团糟糕”。这是,如果“某些事情”发生,就抛出一个错误。
  • 如果正在编写的代码别人也会使用,思考一下他们使用的方式,在特定的情况下抛出错误。
    我们只是为了,更加方便的调试。

try-catch

可能引发错误的代码放在try块中,处理错误的代码放在catch块中。

try {
    //引发错误的代码
}
catch (e){
    //处理错误的代码
}

当在try中发生一个错误时,程序立即停止执行,然后跳到catch块,并传入一个错误对象。检查该对象可以确定从错误中恢复的最佳动作。
当然,还可以加一个finally。在finally中的代码,不管是否有错误发生,最后都会执行。例如:

try {
    //引发错误的代码
}
catch (e){
    //处理错误的代码
}finally {
    //都会执行的代码
}

但是,如果try中包含一个return语句,实际上它必须等到finally块中的代码执行后才能返回。

错误类型

  • Error:所有的错误基本类型。实际上引擎从来不会抛出该类型的错误。
  • EvalError:通过eval()函数执行代码发生错误时抛出。
  • RangeError:一个数字超出它的边界抛出。
  • ReferenceError:期望的对象不存在时抛出—-试图在一个null对象引用上调用一个函数。
  • SyntaxError:给eval()函数传递的代码中有语法错误时抛出。
  • TypeError:变量不是期望的类型抛出。—-new 10或 “prop”in true;
  • URIError:给encodeURI()、encodeURIComponent()、decodeURI()或者decodeURIComponent()等函数传递格式非法的URI字符串时抛出。

可以根据不同的错误类型,来抛出不同的错误消息。

不是你的对象不要动

注意:如果你的代码没有创建这些对象,不要修改他们。
- 原生对象(Object、Array等等)
- dom对象(document)。
- 浏览器对象(BOM)对象(如:window)
- 类库的对象。

原则

1.不覆盖方法。
覆盖一个非自己拥有的对象的方法。如修改document的方法,会导致很多问题。
2.不新增方法。
如:

Array.prototype.reverseSort=function () {
    return this.sort().reverse();
}

在原生对象上新增了方法,可能造成命名冲突。可能会导致难以维护的bug。如果想新增方法可以编写自己的插件。
3.不删除方法
最简单的删除一个方法就是给对应的名字赋值为null;

document.getElementsByClassName=null;

将一个方法设置为null,不管它以前是怎么定义的,现在它已经不能被调用了。
当然如果是对象上的实例,也可以使用delete来删除。

继承

1.基于对象的继承
可以使用ES5的Object.create();来实现继承。

var obj = {
    num: 0,
    content: null,
    name:"tomny",
    sayHi: function () {
        console.log((this.name));
    }
}
var newobj=Object.create(obj);
newobj.sayHi();

同时,也可以在不需要同名变量在新的对象上在重新定义一遍。

newobj.sayHi=function () {
    console.log("jack");
}
newobj.sayHi();//jack
obj.sayHi();//tomny

Object.create()可以指定第二个参数,该参数对象中的属性和方法都将添加到新的对象中。

var myobj=Object.create(obj,{
    name:{
        value:"hannah"
    }
});
myobj.sayHi();//hannah
obj.sayHi();//tomny

2.基于类型的继承

function Person(name) {
    this.name=name;
}
function Author(name) {
    Person.call(this,name);//继承构造器
}
Author.prototype=new Person();

阻止修改

在es5中,有三种锁定修改的级别:
防止扩展: 禁止为对象“添加”属性和方法,但已经存在的属性和方法是可以被修改或删除。
密封: 类似“防止扩展”,而且禁止为对象“删除”已经存在的属性和方法。
冻结:类似“密封”,而且禁止为对象“修改”已存在的属性和方法。

每种锁定的类型都拥有两个方法:一个用来实施操作,另一个用来检测是否应用了相应的操作。如防止扩展,Object.preventExtensions()Object.isExtensible()

var Person={
    name:"Jenny",
};
Object.preventExtensions(Person);//锁定对象
console.log(Object.isExtensible(Person));//false
Person.age=15;
console.log(Person.age);//undefined

上面锁定了Person对象防止被扩展,所以调用Object.isExtensible()函数返回false;


使用Object.seal()函数来密封一个对象。可以使用Object.isSealed()函数来检测一个对象是否已被密封。

Object.seal(Person);//锁定对象
console.log(Object.isExtensible(Person));//false
console.log(Object.isSealed(Person));//true
delete  Person.name;
Person.age=15;
console.log(Person);//{name: "Jenny"}

当一个对象被密封时,它已经存在的属性和方法不能被删除,故在非严格模式下,试图删除上例中的name属性将会悄悄的失败。在严格模式下,试图删除属性或方法将会抛出一个错误。被密封的对象同时也是不可扩展的,所以调用Object.isExtensible()函数返回false;


使用Object.freeze()函数来冻结一个对象。可以使用Object.isFrozen()函数来检查一个对象是否已被冻结。

Object.freeze(Person);//锁定对象
console.log(Object.isExtensible(Person));//false
console.log(Object.isSealed(Person));//true
console.log(Object.isFrozen(Person));//true
delete  Person.name;
Person.age=15;
console.log(Person);//{name: "Jenny"}

被冻结的对象同时也是不可扩展和密封的。被冻结的对象和被密封的对象最大的区别在于,前者禁止任何对已存在属性和方法的修改。

浏览器嗅探

1.用户代理检测(user-agent);

console.log(navigator.userAgent);
//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36
//本文章都是用的是谷歌浏览器

由于浏览器为了确保其兼容性,都会复制另一个浏览器的用户代理字符串。
2.特性检测

if(document.getElementById()){
    //do something
}

在万恶的旧时代这些还是很有用的,现在自从edge出来之后,除了某些特定的,其余的我是觉得没有多大用处了。

最后,为了避免一些js方法不能使用;尽量去检测该方法是否可以使用,而不是检测浏览器版本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编写可维护的JavaScript-编程实践 的相关文章

  • 微信小程序从入门到放弃(五)

    一 字体的大小 font size 像素单位rpx与px的差别 lt view style 61 34 font size 30px 34 gt 我是汉字font size 30px lt view gt br lt view style
  • 微信小程序从入门到放弃(六)

    微信小程序wx hideLoad 安卓不兼容问题 当频繁进行数据交互的时候 xff0c 加载动画 xff0c 在安卓上的时候 xff0c hideLoad xff0c 不能执行 xff0c 使showLoad xff08 xff0c 一直在
  • WIN10的MD5命令

    windows方法 xff1a win键 43 r键输入cmd调出命令行 输入 xff1a 查看MD5值 xff1a certutil hashfile 文件名 MD5 查看 SHA1 certutil hashfile 文件名 SHA1
  • css3样式效果

    一 盒子内圆角 效果图 css样式代码 xff1a width 300px br height 200px br background radial gradient circle at top left transparent 28px
  • 3D背景图动画阴影效果

    先看效果图 原理rotate的使用 当鼠标放到图片的一角处的时候 xff0c 实现该处向下坍缩的效果 xff0c 即用的是rotate的3D属性 xff0c 此时的图片向相应的方向的进行偏转 xff0c 偏转的角度x xff0c y如下图所
  • Vue遇到的bug-01(vue引擎模板报错)

    vue结合webpack的使用 01 报错信息 xff1a 如下图 xff08 配置文件格式错误 xff09 错误的代码 xff1a 如下图 报错信息显示的是配置文件错误 xff08 报错信息的最后一句话是 loaders should b
  • 百度地图API支持HTTPS

    百度地图怎么样才能支持API支持HTTPS 报错信息如下 xff1a Mixed Content The page at https www c 8 com public admin index index html was loaded
  • 数组Array、对象Object、json格式常用的方法小结。

    一 对象Object常用方法 1 初始化方法 var obj 61 var obj 61 new obj var obj 61 Object create null 2 添加元素的方法 dic key 61 value 3 删除key的方法
  • 微信小程序动画特效

    效果 代码见下 xff1a 启动的一瞬间字体在跳动 xff0c 星空在不停的旋转 wxml代码 lt pages welcome welcome wxml gt br lt view class 61 34 stars 34 gt br l
  • 放大镜插件etalage的使用方法

    效果图 如果有人需要etalage的话 xff0c 可以给我留言 xff1b 官方链接Etalage 下载位置 xff1a github 1 使用方法 安装js xff0c css xff0c 文件 xff0c 分别是 xff1a 1 xf
  • 日期插件layDate的使用

    效果图 官方链接 1 layui中的laydate 官方链接 2 贤心的layui 使用说明 只需引入 laydate js 即可HTML结构 lt input span class hljs keyword type span 61 sp
  • jQuery实现可以编辑的表格实例详解

    效果图 点击单个可以进行修改 点击修改所有的表格都可以进行修改 点击保存所有的数据可以获取并打印出来 本人demo需要引入jq文件 代码见如下 xff08 有详细的注解 xff09 span class hljs doctype lt DO
  • input上传图片并预览

    首先说一下input 大家都知道上传文件 xff0c 图片是通过input 的file进行上传的 1 首先是样式 大家都知道input在HTML的代码为 lt input type 61 34 file 34 gt xff1b 在页面的样式
  • PyQt5 使用QT Desinger 布置QChartViewer

    QChartView原来是QT公司的商用包 xff0c 后来开源了 但是相对来说文档说明少 最近想利用QT DESINGER直接拖拉拽在GUI窗体里放QChartViewer xff0c 网上参考部分资料后顺利实现 xff0c 现留作备忘
  • js拳皇特效

    js拳皇特效 效果图 很简单的特效 xff0c 运用了面向对象 xff0c 原型等简单的方法 废话不多说 xff0c 上代码 xff1a span class hljs tag lt span class hljs title script
  • 微信小程序从入门到放弃(七)

    scroll view不显示滚动条 新版本的微信小程序已经把scroll view的滚动条默认为隐藏了 xff0c 而有的业务逻辑需要把滚动条显示出来 xff1b 所以 xff1a 本人查了好久终于找到了解决的方案 xff0c 就是找到滚动
  • cookie+bootstrap-table+抽奖概率算法

    span class hljs comment 获得cookie span span class hljs function span class hljs keyword function span span class hljs tit
  • Vue新手入门-1

    基于vue2 5 9版本 数据绑定v bind 像img这样的标签 xff0c 直接在src里面写 lt img src 61 34 picimg 34 alt 61 34 34 gt xff1b 是不正确的 xff0c 这里需要用v bi
  • Vue新手入门-2

    基于vue2 5 9版本 生命周期vue1 0 created gt beforeCompile gt compiled gt ready gt attached gt detached gt beforeDestroy gt destro
  • cropper.js 裁剪图片并上传(文档翻译+demo)

    官网http fengyuanchen github io cropper 文档https github com fengyuanchen cropper blob master README md v3 x版本 引入 43 使用 span

随机推荐

  • Vue新手入门-3

    基于vue2 5 9版本 定义全局组件 xff08 3种写法 xff09 首先声明一个new Vue xff08 xff09 xff1b 然后在js里面编写 xff1b 最后把注册的组件放入进去即可 xff1b 写法 1 span clas
  • Vue遇到的bug-02(vue中修改了数据但视图无法更新的情况)

    基于vue2 5 9版本 vue中修改了数据但视图无法更新的情况 最近的项目需要用vue处理数组和json的数据类型发现一些问题在这里简单的列举一下 xff1b 因为 JavaScript 的限制 xff0c Vue js 不能检测到下面数
  • Vue遇到的bug-03(VUE之使用高德地图API)

    步骤一 xff1a 申请高德地图密钥 xff1b 步骤二 xff1a 在index html中添加高德地图JavaScript API接口 xff1b span class hljs tag lt span class hljs title
  • 纯css模仿微信switch开关按钮

    业务需要需要做一个微信switch开关 效果图 html样式 span class hljs tag lt span class hljs title label span gt span span class hljs tag lt sp
  • SDN实验环境的搭建UBUNTU 14LTS+MININET+RYU

    RYU是NTT主推的开源SDN 控制器项目 xff0c 采用PYTHON语言 因为工作需要 xff0c 进行了一些尝试 xff0c 现将基础环境的搭建和相关参考资料记录如下 1 系统选择UBUNTU 14 LTS xff0c 采用VMWAR
  • 移动端开发小记

    meta 在我们开发移动端的时候 xff0c 首先在head里面写入如下的代码 span class hljs tag lt span class hljs title meta span span class hljs attribute
  • less 简单用法

    less 示例 声明变量 用 64 span class token atrule span class token rule 64 man color span span class token punctuation span f0f0
  • javascript性能优化(1)

    加载 1 javascript的第一条定律 xff1a 将脚本 xff08 js xff09 放到底部 2 每一个http请求都会造成额外的性能负担 xff0c 下载一个100k的文件比下载四个25k的文件要快 xff1b 减少引用外部脚本
  • javascript性能优化(2)

    数据访问 四种基本数据类型 xff1a 1 直接量 xff1a 仅是自身不存储于特定位置 包括 xff1a 字符串 数字 布尔值 对象 数组 函数 正则表达式 xff0c 具有特殊意义的空值 xff0c 以及未定义 2 变量 xff1a v
  • javascript性能优化(3)

    DOM编程 1 文档对象模型 xff08 DOM xff09 访问的dom越多 xff0c 代码的执行速度就越慢 2 innerHtml和DOM方法 更改dom的时候 xff0c 使用innerHTML xff08 字符串拼接 xff09
  • javascript性能优化(4)

    算法和流程控制 代码整体结构是执行速度的决定因素之一 代码量少不一定运行速度快 xff0c 代码量多也不一定运行速度慢 性能损失与代码组织方式和具体问题解决办法直接相关 循环 1 减少对象成员和数组项查找的次数 span class hlj
  • javascript性能优化(5)

    字符串和正则表达式 span class hljs keyword str span 61 span class hljs string 34 a 34 span 43 span class hljs string 34 b 34 span
  • javascript性能优化(6)

    响应接口 长运行脚本 xff08 500万以上 xff09 最好的办法就是避免他们 接口最好在100毫秒响应用户输入 用定时器让出时间片 当一些JavaScript任务不能再100ms之内完成的时候 xff0c 最好的办法就是 xff1a
  • 一些简单的JavaScript加密/解密

    UTF8编码与解码 xff1a span class hljs function span class hljs keyword function span span class hljs title encodeUTF8 span spa
  • git的基本操作

    新上手一个项目 xff0c 难免会忘记git的一些操作指令 xff0c 于是趁现在工作不是很忙 xff0c 自己便整理一下git的一些基本指令 git拉取远程数据 xff0c 并建立新的分支 git clone url 克隆远程仓库代码 g
  • git clone 加速方法

    查询github global ssl fastly net和github com的IP 安装查询工具 xff1a sudo apt install dnsutils nslookup github com nslookup github
  • javascript性能优化(7)

    Ajax 异步 JavaScript 和 XML Ajax 是高性能 JavaScript 的基石 它可以通过延迟下载大量资源使页面加载更快 它通过在客户端和服 务器之间异步传送数据 xff0c 避免页面集体加载 它还用于在一次 HTTP
  • javascript性能优化(8)

    Programming Practices 编程实践 避免二次评估 JavaScript 与许多脚本语言一样 xff0c 允许你在程序中获取一个包含代码的字符串然后运行它 有四种标准 方法可以实现 xff1a eval xff0c Func
  • 编写可维护的JavaScript-编程风格

    可以使用JSHint对代码进行检查 代码规范可以是使开发更高效 基本的格式化 缩进层级 使用制表符进行缩进 Tab使用空格进行缩进 语句结尾 是不是使用分号看个人喜好 xff0c 书上推荐是不使用 xff1b 但是jshint等工具 xff
  • 编写可维护的JavaScript-编程实践

    UI层的松耦合 1 将JavaScript从css中抽离出来 xff1b 现在大部分已经不支持 xff1b 2 将css从JavaScript中抽离出来 不要直接在js内添加样式 xff1b 如 xff1a e style color 61