JavaScript学习总结(一)——闭包、对象、函数
一、闭包(Closure)
1.1、闭包相关的问题
请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9;方法:找到所有的div,for循环绑定事件。
示例代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>闭包</title>
<style type="text/css">
div{
width: 50px;
height: 50px;
background: lawngreen;
float: left;
margin: 20px;
font:25px/50px "microsoft yahei";
text-align: center;
}
</style>
</head>
<body>
<div>a</div>
<div>b</div>
<div>c</div>
<div>d</div>
<div>e</div>
<div>f</div>
<div>g</div>
<div>h</div>
<div>i</div>
<div>j</div> <script type="text/javascript" src="js/jquery-3.1.1.js" ></script>
<script type="text/javascript">
var divs=document.getElementsByTagName("div");
for (var i=0;i<divs.length;i++) {
divs[i].onclick=function(){
alert(i);
}
} </script>
</body>
</html>
运行结果:
按照平时的思路去做的话,如上图结果所示,点击任何一个div弹出的都是10,因为点击事件的函数内部使用外部的变量i一直在变化,当我们指定click事件时并没有保存i的副本,这样做也是为了提高性能,但达不到我们的目的,我们要让他执行的上下文保存i的副本,这种机制就是闭包。
使用闭包的方法:
var divs=document.getElementsByTagName("div"); for (var i=0;i<divs.length;i++) {
divs[i].onclick=(function(n){
return function(){
alert(n);
}
})(i);
}
运行结果:
n是外部函数的值,但是内部函数(点击事件)需要使用,返回函数前的n被临时驻留在内存中给点击事件使用,简单说就是函数的执行上下文被保存起来,i生成了多个副本。
1.2、理解闭包
闭包概念:当一个内部函数被调用,就会形成闭包,闭包就是能够读取其他函数内部变量的函数,定义在一个函数内部的函,创建一个闭包环境,让返回的这个子程序抓住i,以便在后续执行时可以保持对这个i的引用。内部函数比外部函数有更长的生命周期;函数可以访问它被创建时所处的上下文环境。
Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量
二、对象
对象就是“键/值”对的集合并拥有一个连接到原型(prototype)对隐藏连接。
2.1、对象常量(字面量)
一个对象字面量就是包含在一对花括号中的零个或多个“键/值”对。对象字面量可以出现在任何允许表达式出现的地方。
对象的定义:
//空对象
var obj1={}; //对象中的属性
var obj2={name:"Bob",age:18};
var obj3={"nick name":"Tom"}; //对象中的方法
var obj4={
price:99,
inc:function(){
this.price+=1;
}
}
对象中可包含的内容:
对象常量可以出现在任何允许表达式出现的地方,对象、数组、函数可以相互间嵌套,形式可以多种多样。对象的值可以是:数组,函数,对象,基本数据类型等。
//对象中可包含的内容
var obj5 = [{
name: "jack"
}, {
name: "lucy", //常量
hobby:["读书","看报","电影"], //数组
friend:{name:"mark",height:178,friend:{}}, //对象
show:function(){ //函数
console.log("大家好,我是"+this.name);
}
}];
//对象中的this是动态的,指向的是:调用者
obj5[1].show();
输出:大家好,我是lucy
2.2、取值
方法一:直接使用点号运算
//3取值
var obj6={"nick name":"pig",realname:"Rose"};
console.log(obj6.realname);
//console.log(obj6.nick name); 错误
方法二:使用索引器,当对象中的key有空格时
//3取值
var obj6={"nick name":"pig",realname:"Rose"}; console.log(obj6["realname"]);
console.log(obj6["nick name"]);
2.3、枚举(遍历)
方法一:
var obj7={weight:"55Kg","nick name":"pig",realname:"Rose"}; for (var key in obj7) {
console.log(key+":"+obj7[key]);
}
运行结果:
输出顺序是不能保证的。
2.4、更新与添加
如果对象中存在属性就修改对应值,如果不存在就添加。对象通过引用传递,它们永远不会被复制
var obj1={name:"King"};
obj1.name="Jack"; //修改
obj1.weight=100; //添加属性
obj1.show=function(){ //添加方法
console.log(this.name+","+this.weight);
}
obj1.show();
输出:
var obj1={name:"King"};
obj1.name="Jack"; //修改
obj1.weight=100; //添加属性
obj1.show=function(){ //添加方法
console.log(this.name+","+this.weight);
}
obj1.show(); // //引用
var obj2=obj1; //obj2指向obj1的引用
obj2.name="Tom";
obj1.show();
输出:
2.5、对象的原型
javascript是一种动态语言,与C#和Java这样的静态语言是不一样的;javascript并没有严格的类型,可以简单认为javascript是由对象组成的,对象间连接到原型(prototype)实现功能的扩展与继承。每个对象都链接到一个原型对象,并且可以从中继承属性,所有通过常量(字面量)创建的对象都连接到Object.prototype,它是JavaScript中的顶级(标配)对象,类似高级语言中的根类。
(在该处设置断点,运行,鼠标悬浮在上面时会显示如上图)
现在我们修改系统中的Object对象,添加一个创建方法,指定要创建对象的原型,实现类似继承功能:
<script type="text/javascript">
if(typeof Object.beget!="function")
{
Object.create=function(obj){
//构造函数,用于创建对象
var F=function(){};
//制定由构造函数创建对象的原型
F.prototype=obj;
//调用构造方法创建新对象
return new F();
}
} var Jack={
name:"Jack",
show:function(){
console.log("姓名:"+this.name);
}
} Jack.show();//输出 var Tom=Object.create(Jack);//简单认为是:创建一个对象且继承Jack
Tom.name="Tom";//重写name属性
Tom.show();
</script>
运行结果:
原型关系是一种动态关系,如果修改原型,该原型创建的对象会受到影响。
<script type="text/javascript">
if(typeof Object.beget!="function")
{
Object.create=function(obj){
//构造函数,用于创建对象
var F=function(){};
//制定由构造函数创建对象的原型
F.prototype=obj;
//调用构造方法创建新对象
return new F();
}
} var Jack={
name:"Jack",
show:function(){
console.log("姓名:"+this.name);
}
} Jack.show();//输出 var Tom=Object.create(Jack);//简单认为是:创建一个对象且继承Jack
Tom.name="Tom";//重写name属性 var Mary=Object.create(Jack);
Mary.name="Mary"; //修改原型中的方法
Jack.show=function(){
console.log("姓名——"+this.name);
} Tom.show();
Mary.show();
</script>
运行结果:
2.6、删除
//删除属性
delete mark.name;
//调用方法,输出:姓名:undefined
mark.show(); //删除函数
delete mark.show;
//错误,mark.show is not a function
mark.show();
删除不用的属性是一个好习惯,在某些情况下可能引发内存泄漏。
2.7、封装
使用对象封装的好处是可以减少全局变量的污染机会,将属性,函数都隶属一个对象。
封装前:
var name="func"; //name是全局的,被暴露
i=1; //全局的,没有var关键字盛名的变量是全局的,与位置关系不大
function show(){ //show是全局的,被暴露
console.log("name——>"+name);
console.log(++i);
} //i是全局的
show();//
show();//
运行结果:
封装后:
var fun=function(){
var i=1;
return{
name:"fun",
show:function(){
console.log("name——>"+this.name);
console.log(++i);
}
}
} var a=fun();
a.show(); //
a.show(); // var b=fun();
b.show(); //2,因为被封装,且闭包,i是局部私有的
运行结果:
三、函数
javascript中的函数就是对象,对象就是“键/值”对的集合并拥有一个连接到原型对隐藏连接。
3.1、参数对象 (arguments)
第一个函数中有一个默认对象叫arguments,类似数组,但不是数组,该对象是传递给函数的参数。
function counter(){
var sum=0;
for (var i=0;i<arguments.length;i++) {
sum+=arguments[i];
}
return sum;
} console.log(counter(100,125,50,75,250));
console.log(counter());
运行结果:
这里的arguments是一个隐式对象,不声明也在函数中,内部函数可以访问外部函数的任意内容,但是不能直接访问外部函数的arguments与this对象。
function f1(){
console.log(arguments.length);
f2=function(){
console.log(arguments.length);
}
return f2;
} var ff=f1(2,4,6,8);
ff();
运行结果:
3.2、构造函数
在javascript中对象构造函数可以创建一个对象。
/*构造函数*/
//可以简单的认为是一个类型的定义
function Student(name,age){
this.name=name;
this.age=age;
this.show=function(){
console.log(this.name+","+this.age);
}
} //通过new关键字调用构造函数,创建一个对象tom
var Bob=new Student("Bob",18);
var Tom=new Student("Tom",20); Bob.show();
Tom.show();
运行结果:
3.3、函数调用
3.3.1、call
调用一个对象的一个方法,以另一个对象替换当前对象
call([thisObj[,args])
hisObj 可选项。将被用作当前对象的对象。args 将被传递方法参数序列。
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
示例:
function Student(name,age){
this.name=name;
this.age=age;
}
var Bob=new Student("Bob",18);
var Tom=new Student("Tom",20);
showfun=function(add){
console.log(add+":"+this.name+","+this.age);
} showfun.call(Bob,"Hao are you?");
showfun.call(Tom,"Hello");
运行结果:
call方法中的参数都可以省去,第1个参数表示在哪个对象上调用该方法,或this指向谁,如果不指定则会指向window对象。
示例:
var name="函数";
var age=22;
showfun.call();
运行结果:
3.3.2、apply
apply([thisObj[,argArray]])
应用某一对象的一个方法,用另一个对象替换当前对象,与call类似。
如果 argArray 不是一个有效的数组或者不是arguments对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
对于第一个参数意义都一样,但对第二个参数:
apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])
同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入
示例代码:
function Student(name,age){
this.name=name;
this.age=age;
}
var Bob=new Student("Bob",18);
var Tom=new Student("Tom",20);
applyfun=function(greeting,height){
console.log(greeting+","+this.name+","+this.age+","+height);
}
applyfun.apply(Bob,["Hao are you?","178cm"]);
applyfun.apply(Tom,["Hello","192cm"]);
运行结果:
从上面的示例中可以发现apply的第2个参数是一个数组,数组中的内容将映射到被调用方法的参数中,如果单这样看发现不如call方便,其实如果直接取方法的参数arguments则apply要方便一些。通过简单的变化就可以替代call。
function display(){
applyfun.apply(Tom,arguments);//这里的Tom是上文中创建的对象
}
display("你好","170cm");
运行结果:
javascript里call和apply操作符可以随意改变this指向
如果在javascript语言里没有通过new(包括对象字面量定义)、call和apply改变函数的this指针,函数的this指针都是指向window的。
关于this指针,我的总结是:是谁调用的函数,那么这个函数中的this指针就是它;如果没有明确看出是谁调用的,那么应该就是window调用的,那么this指针就是window。
3.3.3、caller
在一个函数调用另一个函数时,被调用函数会自动生成一个caller属性,指向调用它的函数对象。如果该函数当前未被调用,或并非被其他函数调用,则caller为null。
在JavaScript的早期版本中,Function对象的caller属性是对调用当前函数的函数的引用
function add(){
console.log("add被调用");
//add方法的调用函数,如果调用add方法的不是函数则为null
console.log(add.caller);
} function calc(){
add();
} //直接调用add方法
add();
//间接通过calc方法调用
calc();
运行结果:
caller与this还是有区别的,this是指调用方法的对象,而caller是指调用函数的函数。
function add(n){
console.log("add被调用");
if(n<=2){
return 1;
}
//add方法的调用函数,如果调用add方法的不是函数则为null
return add.caller(n-1)+add.caller(n-2);
} function calc(n){
console.log("calc被调用");
return add(n);
} console.log(calc(3));
结果:
3.3.4、Callee
当函数被调用时,它的arguments.callee对象就会指向自身,也就是一个对自己的引用

function add(n1,n2){
console.log(n1+n2);
//arguments.callee(n1,n2); //指向add方法
return arguments.callee;
} add(1,2)(3,4)(5,6)(7,8)(8,9);

运行结果:
当第1次调用add方法时输入3,立即将函数返回再次调用,每次调用后又返回自己,这样可以实现链式编程。
3.5、立即执行函数表达式 (IIFE)
IIFE即Immediately-Invoked Function Expression,立即执行函数表达式
3.5.1、匿名函数与匿名对象
匿名函数就是没有名称的函数,javascript中经常会使用匿名函数实现事件绑定,回调,实现函数级的私有作用域,如下所示:
function(){
console.log("这是一个匿名函数");
};
匿名对象:

{
name:"foo",
show:function(){
console.log(this.name);
}
}

没有名称的匿名函数也叫函数表达式,它们间是有区别的。
3.5.2、函数与函数表达式
下面是关于函数与函数表达式定义时的区别
a)、函数定义(Function Declaration)
function Identifier ( Parameters ){ FunctionBody }
function 函数名称(参数){函数主体}
在函数定义中,参数(Parameters)标识符(Identifier )是必不可少的。如果遗漏,会报提示错误:
代码:
function(){
console.log("这是一个匿名函数");
};
结果:
b)、函数表达式(Function Expression)
function Identifier(Parameters){ FunctionBody }
函数表达式中,参数和标识符都是可选的,与函数定义的区别是标识符可省去。
其实,"function Identifier(Parameters){ FunctionBody }"并不是一个完整的函数表达式,完整的函数的表达式,需要一个赋值操作。
比如: var name=function Identifier(Parameters){ FunctionBody }
3.5.3、立即执行函数表达式与匿名对象

//1 正常定义函数
function f1(){
console.log("正常定义f1函数");
}; //2 被误解的函数表达式
function(){
console.log("报错Unexpected token (");
}(); //3 IIFE,括号中的内容被解释成函数表达式
(function(){
console.log("IIFE,正常执行");
})(); //4 函数表达式
var f2=function(){
console.log("这也被视为函数表达式");
};

第3种写法为什么这样就能立即执行并且不报错呢?因为在javascript里,括号内部不能包含语句,当解析器对代码进行解释的时候,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明。
如果需要将函数表达式或匿名对象立即执行,可以使用如下方法:

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>IIFE</title>
</head> <body>
<script type="text/javascript">
//调用匿名函数
(function() {
console.log("这是一个函数表达式");
})(); //调用匿名对象
({
name: "foo",
show: function() {
console.log(this.name);
}
}).show(); console.log({
a: 1
}.a); console.log({
a: function() {}
}.a());
</script>
</body> </html>

运行结果:
3.5.4、各种IIFE的写法

//最常用的两种写法
(function(){ /* code */ }()); // 老师推荐写法
(function(){ /* code */ })(); // 当然这种也可以 // 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义
// 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
// 但是两者交换则会报错
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }(); // 如果你不怕代码晦涩难读,也可以选择一元运算符
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }(); // 你也可以这样
new function(){ /* code */ }
new function(){ /* code */ }() // 带参

如果是函数表达式,可直接在其后加"()"立即执行。
如果是函数声明,可以通过"()"、"+"、"-"、"void"、"new"等运算符将其转换为函数表达式,然后再加"()"立即执行。
3.5.5、参数
函数表达式也是函数的一种表达形式,同样可以像函数一样使用参数,如下所示:
(function (n){
console.log(n);
})(100);
输出:100
其实通过IIFE还能形成一个类似的块级作用域,当块内的程序在使用外部对象时将优先查找块内的对象,再查找块外的对象,依次向上。
(function(win,undfd){
win.console.log("Hello"==undfd);
})(window,undefined);
3.5.6、添加分号
为了避免与其它的javascript代码产生影响后报错,常常会在IIFE前增加一个分号,表示前面所有的语句都结束了,开始新的一语句。
var k=100
(function (n){
console.log(n);
})(k);
上面的脚本会报错,因为javascript解释器会认为100是函数名。
var k=100
;(function (n){
console.log(n);
})(k);
这样就正确了,在javascript中一行语句的结束可以使用分号,也可以不使用分号,因为一般的自定义插件会使用IIFE,这是一段独立的代码,在应用过程中不能保证用户会加上分号,所以建议在IIFE前加上分号。
3.5.7、IIFE的作用
1)、提高性能
减少作用域查找时间。使用IIFE的一个微小的性能优势是通过匿名函数的参数传递常用全局对象window、document、jQuery,在作用域内引用这些全局对象。JavaScript解释器首先在作用域内查找属性,然后一直沿着链向上查找,直到全局范围。将全局对象放在IIFE作用域内提升js解释器的查找速度和性能。
function(window, document, $) { }(window, document, window.jQuery);
2)、压缩空间
通过参数传递全局对象,压缩时可以将这些全局对象匿名为一个更加精简的变量名
function(w, d, $) { }(window, document, window.jQuery);
3)、避免冲突
匿名函数内部可以形成一个块级的私有作用域。
4)、依赖加载
可以灵活的加载第三方插件,当然使用模块化加载更好(AMD,CMD),示例如下。
A.html与B.html文件同时引用公用的common.js文件,但是只有A.html需要使用到StuObj对象,B.html不需要,但使用其它方法。
Student.js

var StuObj = {
getStu: function(name) {
return new Student(name);
}
} /*构造函数*/
function Student(name) {
this.name = name;
this.show = function() {
console.log("Hello," + this.name);
}
}

Common.js

function other1() {} function other2() {} (function($) {
if($) {
$.getStu("Tom").show();
}
})(typeof StuObj=="undefined"?false:StuObj);

A.HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>A</title>
</head>
<body>
<script src="js/Student.js" type="text/javascript" charset="utf-8"></script>
<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

B.HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
other1();
</script>
</body>
</html>

3.5.8、IIFE的变形
也许有人会说IIFE将参数放在最后,需要移动到文档的末尾才能看到参数,比较麻烦,那么可以将IIFE变形为如下形式:

(function(n){
console.log(n); //认为这里有30000代码 }(100));

如果中间有很长的代码,参数100只有到文档的末尾才可以看得到,变形后的结果:

(function(exp){
exp(100);
}(function(n){
console.log(n);
//认为这里有30000代码
}));

修改后的代码中有两个函数表达式,一个作为参数,就是我们主要要完成的功能向控制台输出数字,另一个作来IIFE立即执行的函数,主要的功能函数变成的IIFE的参数了。

(function(win, doc, $) { }(window, document, jQuery)); (
function(library) {
library(window, document, window.jQuery);
}
(function(window, document, $) { })
);

bootstrap的写法:

+function(yourcode) { yourcode(window.jQuery, window, document); }(function($, window, document) {
$(function() {}); //jQueryDOM加载完成事件
});

结合call或apply的写法:
(function(x){console.log(x)}).call(window,888);
(function(x){console.log(x)}).apply(window,[999]);
输出:888 999
JavaScript学习总结(一)——闭包、对象、函数的更多相关文章
- JavaScript学习06 JS事件对象
JavaScript学习06 JS事件对象 事件对象:当事件发生时,浏览器自动建立该对象,并包含该事件的类型.鼠标坐标等. 事件对象的属性:格式:event.属性. 一些说明: event代表事件的状 ...
- Javascript学习6 - 类、对象、继承
原文:Javascript学习6 - 类.对象.继承 Javasciprt并不像C++一样支持真正的类,也不是用class关键字来定义类.Javascript定义类也是使用function关键字来完成 ...
- JavaScript:学习笔记(9)——Promise对象
JavaScript:学习笔记(9)——Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...
- JavaScript:学习笔记(10)——XMLHttpRequest对象
JavaScript:学习笔记(10)——XMLHttpRequest对象 XHR对象 使用XMLHttpRequest (XHR)对象可以与服务器交互.您可以从URL获取数据,而无需让整个的页面刷新 ...
- JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象
一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...
- JavaScript学习总结(二)——闭包、IIFE、apply、函数与对象
一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...
- JavaScript学习总结(三)——闭包、IIFE、原型、函数与对象
一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...
- JavaScript学习总结-技巧、有用函数、简洁方法、编程细节
整理JavaScript方面的一些技巧.比較有用的函数,常见功能实现方法,仅作參考 变量转换 //edit http://www.lai18.com var myVar = "3.14159 ...
- JavaScript学习总结-技巧、实用函数、简洁方法、编程细节
整理JavaScript方面的一些技巧,比较实用的函数,常见功能实现方法,仅作参考 变量转换 var myVar = "3.14159", str = ""+ ...
- Javascript学习笔记:闭包题解(3)
代码: function assignHandler(){ var element=document.getElementById('someElementId'); element.onclick= ...
随机推荐
- 28.数组中出现次数超过长度一半的数字(python)
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- (转)Spring实例化
标签:SpringContextUtil,getBean 手动获取Bean 方法一 不用配置xml,直接java代码实现 /** * 工厂模式选择Bean类 */ public class MyBe ...
- Nowcoder 练习赛26 D xor序列 ( 线性基 )
题目链接 题意 : 中文题.点链接 分析 : 对于给定的 X 和 Y 假设存在一个 Z 使得 X (xor) Z = Y 做一个变形 X (xor) Z (xor) Y = 0 X (xor) Y = ...
- scrollWidth、clientWidth、offsetWidth、width的区别
scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大. clientWidth:对象内容的可视区的宽度,不包滚动条等边线,会随对象显示大小的变化而改变. off ...
- nginx负载均衡 之集群概念与负载均衡
集群介绍 为什么要用集群
- MQTT通配符
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 后盾网lavarel视频项目---4、lavarel和vue都是{{}}表示变量,如何解决冲突
后盾网lavarel视频项目---4.lavarel和vue都是{{}}表示变量,如何解决冲突 一.总结 一句话总结: @{{videos}}:@符号表示lavarel不处理:textarea nam ...
- vs2015使用低版本编译的openssl问题
用Vs2005编译的openssl,在vs2015中使用就悲剧了,报如下错误 >libeay32.lib(cryptlib.obj) : error LNK2019: 无法解析的外部符号 __v ...
- Jquery 选择器的用法
用js 动态生成<ul>标签的<li>条目,因为在动态的创建过程中li的点击事件是不太方便的,因此采用JQuery 的类选择器来实现. html代码: <div id=& ...
- linux 代码更新-打包-重启脚本
#! /bin/sh base=/home/project/myblog cd $base git pull ] then echo "Error in git pull!!! Stop d ...