前端学习--js.2
- 写一个通用的事件侦听器函数
- markyun.Event = {
- //页面加载完成后
- readyEvent :function(fn) {
- if(fn==null) {
- fn=document;
- }
- varoldonload = window.onload;
- if(typeofwindow.onload !='function') {
- window.onload = fn;
- }else{
- window.onload =function() {
- oldonload();
- fn();
- };
- }
- },
- //视能力分别使用dom0||dom2||IE方式 来绑定事件
- //参数: 操作的元素,事件名称 ,事件处理程序
- addEvent :function(element, type, handler) {
- if(element.addEventListener) {
- //事件类型、需要执行的函数、是否捕捉
- element.addEventListener(type, handler,false);
- }else if(element.attachEvent) {
- element.attachEvent('on'+ type,function() {
- handler.call(element);
- });
- }else{
- element['on'+ type] = handler;
- }
- },
- //移除事件
- removeEvent :function(element, type, handler) {
- if(element.removeEnentListener) {
- element.removeEnentListener(type, handler,false);
- }else if(element.datachEvent) {
- element.detachEvent('on'+ type, handler);
- }else{
- element['on'+ type] =null;
- }
- },
- //阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
- stopPropagation :function(ev) {
- if(ev.stopPropagation) {
- ev.stopPropagation();
- }else{
- ev.cancelBubble =true;
- }
- },
- //取消事件的默认行为
- preventDefault :function(event) {
- if(event.preventDefault) {
- event.preventDefault();
- }else{
- event.returnValue =false;
- }
- },
- //获取事件目标
- getTarget :function(event) {
- returnevent.target || event.srcElement;
- },
- //获取event对象的引用,取到事件的所有信息,确保随时能使用event;
- getEvent :function(e) {
- varev = e || window.event;
- if(!ev) {
- varc =this.getEvent.caller;
- while(c) {
- ev = c.arguments[0];
- if(ev && Event == ev.constructor) {
- break;
- }
- c = c.caller;
- }
- }
- returnev;
- }
- };
67、["1", "2", "3"].map(parseInt) 答案是多少?
[1,NaN,NaN]
68、关于事件,IE与火狐的事件机制有什么区别? 如何阻止冒泡?
我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为。
事件处理机制:IE是事件冒泡、火狐是 事件捕获;
ev.stopPropagation();
69、什么是闭包(closure),为什么要用它?
闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
闭包的特性:
(1)函数内再嵌套函数
(2)内部函数可以引用外层的参数和变量
(3)参数和变量不会被垃圾回收机制回收
HTML:
<!-- li节点的onclick事件都能正确的弹出当前被点击的li索引 -->
<ul id="testUL">
<li> index = 0</li>
<li> index = 1</li>
<li> index = 2</li>
<li> index = 3</li></ul>
JS:
<script type="text/javascript">
var nodes = document.getElementsByTagName("li");
for(i = 0;i<nodes.length;i+= 1){
nodes[i].onclick = (function(i){
return function() {
console.log(i);
} //不用闭包的话,值每次都是4 })(i);
}</script>
然后我们看看下面的一段代码,这是对闭包作用的非常直白的描述:
function say667() {// Local variable that ends up within closure
var num = 666;
var sayAlert = function() {
alert(num);
}
num++;
return sayAlert;
}var sayAlert = say667();
sayAlert()//执行结果应该弹出的667
执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在
使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源
因为say667()的内部函数的执行需要依赖say667()中的变量
- javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?
除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。
为什么用严格模式
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
"严格模式"体现了Javascript更合理、更安全、更严谨的发展方向,包括IE 10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱它。
另一方面,同样的代码,在"严格模式"中,可能会有不一样的运行结果;一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行。掌握这些内容,有助于更细致深入地理解Javascript,让你变成一个更好的程序员。
进入标志
"use strict";
如何调用
(1)针对单个脚本
<script>
"use strict";
console.log("这是严格模式。");
</script>
(2)针对单个函数
functionstrict(){
"use strict";
return"这是严格模式。";
}
functionnotStrict() {
return"这是正常模式。";
}
语法与行为改变
严格模式对Javascript的语法和行为,都做了一些改变。
5.1 全局变量显式声明
在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。
"use strict";
v = 1;//报错,v未声明
for(i = 0; i < 2; i++) {//报错,i未声明
}
因此,严格模式下,变量都必须先用var命令声明,然后再使用。 禁止this关键字指向全局对象
functionf(){
return!this;
}
//返回false,因为"this"指向全局对象,"!this"就是false
functionf(){
"use strict";
return!this;
}
//返回true,因为严格模式下,this的值为undefined,所以"!this"为true。
因此,使用构造函数时,如果忘了加new,this不再指向全局对象,而是报错。
functionf(){
"use strict";
this.a = 1;
};
f();//报错,this未定义
禁止删除变量
严格模式下无法删除变量。只有configurable设置为true的对象属性,才能被删除。
"use strict";
varx;
deletex;//语法错误
varo = Object.create(null, {'x': {
value: 1,
configurable:true
}});
deleteo.x;//删除成功
对象不能有重名的属性
正常模式下,如果对象有多个重名属性,最后赋值的那个属性会覆盖前面的值。严格模式下,这属于语法错误。
"use strict";
varo = {
p: 1,
p: 2
};//语法错误
函数不能有重名的参数
正常模式下,如果函数有多个重名的参数,可以用arguments[i]读取。严格模式下,这属于语法错误。
"use strict";
functionf(a, a, b) {//语法错误
return;
}
71、如何判断一个对象是否属于某个类?
javascript中检测对象的类型的运算符有:typeof、constructor、instanceof。
typeof:typeof是一个一元运算符,返回结果是一个说明运算数类型的字符串。如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在)。 但 typeof 的能力有限,其对于Date、RegExp、Array类型返回的都是"object"。所以它只在区别对象和原始类型的时候才有用。要区一种对象类型和另一种对象类型,必须使用其他的方法。
instanceof 运算符:instanceof 运算符要求其左边的运算数是一个对象,右边的运算数是对象类的名字或构造函数。如果 object 是 class 或构造函数的实例,则 instanceof 运算符返回 true。如果 object 不是指定类或函数的实例,或者 object 为 null,则返回 false。instanceof方法可以判断变量是否是数组类型,但是只限同一全局环境之内,在一个页面有多个iframe的情况下,instanceof失效。
constructor 属性: JavaScript中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,常用于判断未知对象的类型。如给定一个求知的值 通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。
Object.prototype.toString.call():该方法是目前为止发现的判断一个对象类型的最好的办法。
72、Javascript中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?
hasOwnProperty
73、[].forEach.call($$("*"),function(a){ a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16) })
能解释一下这段代码的意思吗?
(1)call:call(thisObj,arg1,arg2,arg3)
1 |
|
就是用$$('a')来替代[],
好 那么到了第二个问题$$('a')是什么意思
(2)$$('a')
你可以在自己的浏览器上面运行一下,就是页面上所有的a标签
然后再继续
(3)function(a){}
无疑就是$$('a')组成的数组要进行的回调函数了
好我们再看里面的东西
(4)~~
看在浏览器上面的运行
1 2 3 4 5 6 7 8 |
|
所以~~的作用就相当于parseInt
- js延迟加载的方式有哪些?
js的延迟加载有助与提高页面的加载速度,以下是延迟加载的几种方法:
(1)使用setTimeout延迟方法的加载时间
延迟加载js代码,给网页加载留出更多时间
<script type="text/javascript">
function A(){
$.post("/lord/login",{name:username,pwd:password},function(){
alert("Hello");
});
}
$(function (){
setTimeout('A()',1000);//延迟1秒
})</script>
(2)让js最后加载
例如引入外部js脚本文件时,如果放入html的head中,则页面加载前该js脚本就会被加载入页面,而放入body中,则会按照页面从上倒下的加载顺序来运行javascript的代码~~~ 所以我们可以把js外部引入的文件放到页面底部,来让js最后引入,从而加快页面加载速度
(3)上述方法2也会偶尔让你收到Google页面速度测试工具的“延迟加载javascript”警告。所以这里的解决方案将是来自Google帮助页面的推荐方案。
//
这些代码应被放置在
</body>标签前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtOnload(){
varelement = document.createElement("script");
element.src ="defer.js";
document.body.appendChild(element);
}
if(window.addEventListener)
window.addEventListener("load", downloadJSAtOnload,false);
else if(window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
elsewindow.onload = downloadJSAtOnload;</script>
这段代码意思是等到整个文档加载完后,再加载外部文件“defer.js”。
使用此段代码的步骤:
1).复制上面代码
2).粘贴代码到HTML的标签前 (靠近HTML文件底部)
3).修改“defer.js”为你的外部JS文件名
4).确保你文件路径是正确的。例如:如果你仅输入“defer.js”,那么“defer.js”文件一定与HTML文件在同一文件夹下。
注意:这段代码直到文档加载完才会加载指定的外部js文件。因此,不应该把那些页面正常加载需要依赖的javascript代码放在这里。而应该将JavaScript代码分成两组。一组是因页面需要而立即加载的javascript代码,另外一组是在页面加载后进行操作的javascript代码(例如添加click事件或其他东西)。这些需等到页面加载后再执行的JavaScript代码,应放在一个外部文件,然后再引进来。
75、同步和异步的区别?
同步:
同步的思想是:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。
异步:
将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了。你可以关闭界面了。
同步,是所有的操作都做完,才返回给用户结果。即写完数据库之后,在相应用户,用户体验不好。
异步,不用等所有操作等做完,就相应用户请求。即先相应用户请求,然后慢慢去写数据库,用户体验较好。
异步操作例子:
为了避免短时间大量的数据库操作,就使用缓存机制,也就是消息队列。先将数据放入消息队列,然后再慢慢写入数据库。
引入消息队列机制,虽然可以保证用户请求的快速响应,但是并没有使得我数据迁移的时间变短(即80万条数据写入mysql需要1个小时,用了redis之后,还是需要1个小时,只是保证用户的请求的快速响应。用户输入完http url请求之后,就可以把浏览器关闭了,干别的去了。如果不用redis,浏览器不能关闭)。
同步就没有任何价值了吗?
银行的转账功能。
76、页面编码和被请求的资源编码如果不一致如何处理?
s编码和页面编码不一致,导致提示变量未定义的解决方法 (2011-06-30 10:27:02)转载▼
标签: js跨域 变量未定义 js编码 it 分类: JS
今天在测试项目的时候,由于是和其他站合作的,引用合作方的js文件,
有个js函数调用,调用时会使用包含合作方js里的变量,
可是竟然不兼容ie6、ie7、360等主流浏览器。那必须得解决是吧。
原本以为是跨域问题,如果是跨域问题,也应该提示没权限,可是没提示。
提示的是某某变量未定义,我就百度了。 没找到我想要的答案,
灵机一动想到是不是编码问题 。于是在js后加了 charset="utf-8" 这个 。
发现还真好了。 。 绕了好些圈子 。 这次记下了。避免下次再遇到类似的状况。
比如:http://www.yyy.com/a.html 中嵌入了一个http://www.xxx.com/test.js
a.html 的编码是gbk或gb2312的。 而引入的js编码为utf-8的 ,那就需要在引入的时候
<script src="http://www.xxx.com/test.js"charset="utf-8"></script>
同理,如果你的页面是utf-8的,引入的js是gbk的,那么就需要加上charset="gbk".
77、AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)规范区别?
AMD
AMD规范其实只有一个主要接口 define(id,dependencies,factory),它要在声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置
[javascript]view plain copy
- define("module", ["dep1","dep2"],function(d1, d2) {
- returnsomeExportedValue;
- });
- require(["module","../file"],function(module, file) {/* ... */});
CMD
CMD规范和AMD相似,尽量保持简单,并且与CommonJS和NodeJS的Modules规范保持了很大的兼容性。
[javascript]view plain copy
- define(function(require, exports, module) {
- var$ = require('jquery');
- varSpinning = require('./spinning');
- exports.doSomething = ...
- module.exports = ...
- })
ES6 包含了很多新的语言功能,且这些语言功能使得 JS 更加强大更富有表现力。
ECMAScript 的范围是什么?
JavaScript 编程语言是由 ECMAScript 名下的 ECMA 进行标准化制定的( ECMA 是和 W3C 一样的标准化组织 )。除此之外,ECMAScript 可如下定义:
内置对象和函数的标准库 - JSON ,数学( Math ), 数组方法( Array methods ),对象内省的方法( Object introspection methods )等等。
新的标准
上周, ECMAScript 语言规范的最终草案,第 6 版,被提交给 ECMA 大会进行审查。这意味着什么呢?
这意味着这个夏天,对于核心的 JavaScript 编程语言,我们将有一个新的标准。
这是一个大新闻。新的 JS 语言不是每天都可能出现的。 上一个版本,ES5,可以追溯到 2009 年。从那时起,ES 标准委员会就一直致力于 ES6 的制定直至今日。
计数到 6
ECMAScript 标准的先前的版本分别编号为 1,2,3 和 5。
ECMAScript 是一个充满活力的语言且其语言的演化还不完整。在未来的 ECMAScript 的版本中将有较大提升的技术的声明。
兑现承诺
本系列旨在向你展示 ES6 如何通过检查其新功能来给JavaScript程序员提供新的写代码体验。
我们将以一个典型的“功能缺失”作为开始。“功能缺失”是我在过去的十年的时间内一直渴望能从 JavaScript 那看到的。所以,让我们一起去探索 ES6 迭代器和新的 for-of 循环。
79、ECMAScript6 怎么写class么,为什么会出现class这种东西?
ES6 的 class 有优点也有缺点,整体说来,是利大于弊的,推荐使用。
缺点主要有:
(1)语法和语义难对上了,也就是说从书写出来的代码是看不出来内部是通过原型实现相关功能点的。
(2)类的写法有一定的限制性,不再像原型那么灵活了。
最后, ES6 的类只是一个基础形式,后续 ECMAScript 版本还会继续添加一些内容进去,比如 trait 、不可变实例等。
80、documen.write和 innerHTML的区别?
(2)两者都可向页面输出内容,innerHTML比document.write更灵活。
在读模式下,innerHTML属性返回与调用元素的所有子节点对应的HTML标记,在写模式下,innerHTML会根据指定的值创建新的DOM树替换调用元素原先的所有子节点。
通过document.write插入<script>元素会自动执行其中的脚本;
大多数浏览器中,通过innerHTML插入<script>元素并不会执行其中的脚本。
严格的说,JavaScript 是基于对象的编程语言,而不是面向对象的编程语言。
在面向对象的编程语言中(如Java、C++、C#、PHP等),声明一个类使用 class 关键字。
例如:
但是在JavaScript中,没有声明类的关键字,也没有办法对类的访问权限进行控制。
JavaScript 使用函数来定义类。
语法:
function className(){
// 具体操作
}
例如,定义一个Person类:
this.name=" 张三 "; // 定义一个属性 name
this.say=function(){ // 定义一个方法 say()
document.write("嗨!大家好,我的名字是 " + this.name + " ,性别是 " + this.sex + "。");
创建对象的过程也是类实例化的过程。
在JavaScript中,创建对象(即类的实例化)使用 new 关键字。
语法:
new className();
将上面的 Person 类实例化:
运行代码,输出如下内容:
嗨!大家好,我的名字是 张三 ,性别是 男 。
定义类时可以设置参数,创建对象时也可以传递相应的参数。
下面,我们将Person类重新定义:
this.name=name; // 定义一个属性 name
this.say=function(){ // 定义一个方法 say()
document.write("嗨!大家好,我的名字是 " + this.name + " ,性别是 " + this.sex);
var zhangsan=new Person("小丽","女");
运行代码,输出如下内容:
嗨!大家好,我的名字是 小丽 ,性别是 女 。
$.fn.stringifyArray = function(array) {
$.fn.parseArray = function(array) {
83、jQuery 的属性拷贝(extend)的实现原理是什么,如何实现深拷贝?
语法:jQuery.extend( [deep ], target, object1 [, objectN ] )
关于$.extend()的用法网上有很多文章,在这里指向写写对深浅拷贝的理解
深浅拷贝对应的参数就是[deep],是可选的,为true或false。默认情况是false(浅拷贝),并且false是不能够显示的写出来的。如果想写,只能写true(深拷贝)~~
浅拷贝(false 默认):如果第二个参数对象有的属性第一个参数对象也有,那么不会进行相同参数内部的比较,直接将第一个对象的相同参数覆盖。
深拷贝(true):如果第二个参数对象有的属性第一个参数对象也有,还要继续在这个相同的参数向下一层找,比较相同参数的对象中是否还有不一样的属性,如果有,将其继承到第一个对象,如果没有,则覆盖。
varobject1 = {
apple: 0,
banana: {
weight: 52,
price: 100
},
cherry: 97
};varobject2 = {
banana: {
price: 200
},
durian: 100
};
//默认情况浅拷贝
//object1--->{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}
//object2的banner覆盖了object1的banner,但是weight属性未被继承
//$.extend(object1, object2);
//深拷贝
//object1--->{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}
//object2的banner覆盖了object1的banner,但是weight属性也被继承了呦
$.extend(true,object1, object2);
console.log('object1--->'+JSON.stringify(object1));
84、jquery.extend 与 jquery.fn.extend的区别?
它是为jQuery类添加类方法,可以理解为添加静态方法。如:
min: function(a, b) { return a < b ? a : b; },
max: function(a, b) { return a > b ? a : b; }
jQuery.min(2,3); // 2
jQuery.max(4,5); // 5
b. jQuery.extend(target, object1, [objectN])用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);
结果:settings == { validate: true, limit: 5, name: "bar" }
(2). jQuery.fn.extend(object);
$.fn是指jQuery的命名空间,fn上的成员(方法function及属性property),会对jQuery实例每一个有效。
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {//....
原来 jQuery.fn = jQuery.prototype.
所以,它是对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。
比如我们要开发一个插件,做一个特殊的编辑框,当它被点击时,便alert 当前编辑框里的内容。可以这么做:
$("#input1") 为一个jQuery实例,当它调用成员方法 doAlertWhileClick后,便实现了扩展,每次被点击时它会先弹出目前编辑里的内容。
85、谈一下Jquery中的bind(),live(),delegate(),on()的区别?
bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数
$("a").bind("click",function(){alert("ok");});
live(type,[data],fn) 给所有匹配的元素附加一个事件处理函数,即使这个元素是以后再添加进来的
$("a").live("click",function(){alert("ok");});
delegate(selector,[type],[data],fn) 指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数
$("#container").delegate("a","click",function(){alert("ok");})
on(events,[selector],[data],fn) 在选择元素上绑定一个或多个事件的事件处理函数
.live()则是通过冒泡的方式来绑定到元素上的。更适合列表类型的,绑定到document DOM节点上。和.bind()的优势是支持动态数据。
.delegate()则是更精确的小范围使用事件代理,性能优于.live()
.on()则是最新的1.9版本整合了之前的三种方式的新事件绑定机制
86、JQuery一个对象可以同时绑定多个事件,这是如何实现的?
- jQuery("#id").click(func1).mouseover(func2)//方法连写,func为方法的名字
- jQuery("#id").click(function(){//你的具体方法实现}),mouser(function(){//你的具体方法实现});
- jQuery("#id").bind("click mouseover",func)//两个事件中间有空格 ,func为方法的名字
- jQuery("#id").bind("load scroll",function(){//你的具体方法实现});
87、是否知道自定义事件。jQuery里的fire函数是什么意思,什么时候用?
1种是把那个函数放到ready函数外面。 第2种是在ready函数里面加上window.deleteStu = deleteStu; 即: $(function(){ function deleteStu(id){ alert(id); } window.deleteStu = deleteStu; }
jQuery选择器通俗来讲就是一个获取html元素的工具。比如,$("p") 选取 <p> 元素,$("p")是jQuery的选择器的写法,这么写就可以获取(选取)html里的<p>元素。
jQuery选择器包括元素选择器、属性选择器、CSS选择器。(个人感觉这个分类比较扯淡)
注意:属性选择器的意思并不是选择属性,而是根据属性选择元素。
html代码里的开始标签+内容+结束标签就构成一个元素,英文是element。
属性估计大家都清楚,比如标签<body bgcolor="red">中,bgcolor="red"就是属性。
也就是说,属性是在标签中的;而在不混淆的情况下,我们经常把元素称作为标签(部分人包括我经常这样),也不是一个很大的问题。
当然,这只是最简单的情况下。$写法的在这种情况下其实也是调用getElementById(),但复杂情况则通过jQuery选择器的复杂实现。
w3c上说:jQuery 使用 CSS 选择器来选取 HTML 元素。。
在jQuery中最快的选择器是ID选择器 ($('#someid')). 这是因为它直接映射为JavaScript的getElementById()方法。
选择单个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </div> |
1 |
var traffic_button = $('#content .button'); |
1 |
var traffic_button = $('#traffic_button'); |
在我们讨论选择多个元素的时候,我们真正需要知道的是DOM的遍历和循环才是性能低下的原因。为了尽量减少性能损失, 总是使用最近的父ID去寻找。
1 |
var traffic_lights = $('#traffic_light input'); |
在jQuery中第二快的选择器就是Tag选择器 ($('head')). 而这是因为它直接映射到JavaScript的getElementsByTagName()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </div> |
总是在一个Class前面加上一个tag名字(记得从一个ID传下来)
1 |
var active_light = $('#traffic_light input.on'); |
1 |
var content = $('div#content'); |
1 |
var traffic_light = $('#content #traffic_light'); |
养成保存jQuery对象到一个变量上(就像上面的例子)的习惯。例如,不要这样做:
1 2 3 4 5 6 7 |
$('#traffic_light input.on).bind('click', function(){...}); $('#traffic_light input.on).css('border', '3px dashed yellow'); $('#traffic_light input.on).css('background-color', 'orange'); $('#traffic_light input.on).fadeIn('slow'); |
取而代之,首现保存jQuery变量到一个本地变量后,再继续你的操作。
1 2 3 4 5 6 7 8 9 |
var $active_light = $('#traffic_light input.on'); $active_light.bind('click', function(){...}); $active_light.css('border', '3px dashed yellow'); $active_light.css('background-color', 'orange'); $active_light.fadeIn('slow'); |
提示:使用$前辍表示我们的本地变量是一个jQuery包集。记住,不要在你的应该程序里出现一次以上的jQuery重复的选择操作。 额外提示:延迟存储jQuery对象结果。
// Define an object in the global scope (i.e. the window object) window.$my ={ // Initialize all the queries you want to use more than once head : $('head'), traffic_light : $('#traffic_light'), traffic_button : $('#traffic_button')}; function do_something(){ // Now you can reference the stored results and manipulate them var script = document.createElement('script'); $my.head.append(script); // When working inside functions, continue to save jQuery results // to your global container. $my.cool_results = $('#some_ul li'); $my.other_results = $('#some_table td'); // Use the global functions as you would a normal jQuery result $my.other_results.css('border-color', 'red'); $my.traffic_light.css('border-color', 'green'); } |
1 2 3 4 5 6 7 8 9 |
var $active_light = $('#traffic_light input.on'); $active_light.bind('click', function(){...}) .css('border', '3px dashed yellow') .css('background-color', 'orange') .fadeIn('slow'); |
jQuery允许我们在一个包集上附加其它的选择器。因为我们已经在本地变量里保存了父对象这样会减少以后在选择器上的性能开销。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </div> |
例如,我们可以利用子查询缓存active和inactive lights以便后面的操作。
1 2 3 4 5 |
var $traffic_light = $('#traffic_light'), $active_light = $traffic_light.find('input.on'), $inactive_lights = $traffic_light.find('input.off'); |
提示:可以用逗号隔开一次定义多个本地变量,这样可以节省一些字节。
1 2 3 4 5 6 7 8 9 |
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'); // jQuery selects our <ul> element for (var i=0, l=top_100_list.length; i<l; i++){ $mylist.append('<li>' + top_100_list[i] + '</li>'); } |
取而代之,我们希望在插入DOM结构之前先在一个字符串里创建一套元素。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'), // jQuery selects our <ul> element top_100_li = ""; // This will store our list items for (var i=0, l=top_100_list.length; i<l; i++){ top_100_li += '<li>' + top_100_list[i] + '</li>'; } $mylist.html(top_100_li); |
更快的做法,在插入DOM结构之前我们应该总是在一个父节点里包含许多元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'), // jQuery selects our <ul> element top_100_ul = '<ul id="#mylist">'; // This will store our entire unordered list for (var i=0, l=top_100_list.length; i<l; i++){ top_100_ul += '<li>' + top_100_list[i] + '</li>'; } top_100_ul += '</ul>'; // Close our unordered list $mylist.replaceWith(top_100_ul); |
如是你照着上面的做了还是对性能有些迷惑的话,可以参考以下内容:
* 试一下jQuery提供的Clone()方法。Clone()方法创建节点数的拷贝,随后你可以在这个副本中进行操作。
1 2 3 4 5 |
$('#myList li).bind('click', function(){ $(this).addClass('clicked'); // do stuff }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$('#myList).bind('click', function(e){ var target = e.target, // e.target grabs the node that triggered the event. $target = $(target); // wraps the node in a jQuery object if (target.nodeName === 'LI') { $target.addClass('clicked'); // do stuff } }); |
父节点担当着发报机的工作,可以在触发了事件的目标element上做一些工作。如果你发现自己把一个event listener帮定到很多个element上,那么你这种做法是不正确的。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <script type="text/javascript>mylib.traffic_light.init();</script> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
var mylib ={ article_page : { init : function() { // Article page specific jQuery functions. } }, traffic_light : { init : function() { // Traffic light specific jQuery functions. } } } |
1 2 3 4 5 |
$(window).load(function(){ // jQuery functions to initialize after the page has loaded. }); |
多余的功能,如拖拽、帮定可视化效果和动画、预读取图片等,使用这种方法比较好。
学习和最有效的使用jQuery,最好的方法就是去查jQuery的文档和手册了。
以上就是本文的全部内容,了解更多jQuery的语法,大家可以查看:《jQuery 1.10.3 在线手册》,也希望大家多多支持脚本之家。
jqueryui是jquery的一个插件,jquery是对javascript的封装,而jqueryui是一个基于jquery的一个UI方面的框架。
个人觉得完全可以解释了。
在就是easyui了,也是最近刚刚接触到的,这么earyui和jquery有什么区别了?
jquery ui 是jquery开发团队 开发,适用于网站式的页面。jquery easyui 是第三方基于jquery开发,适用于应用程序式的页面。
jQueryUI: http://jqueryui.com/demos/tabs/#manipulation
jQuery自带的一个可选UI库,但是非常可惜,一些关键的组件没有包含进去,如TreeView, DataGrid,还需要寻找第三方的插件。
EasyUI:
是某公司开发的一套对私免费,对公收费的UI库,基于GNU开源协议,不过只有付费了才能买到他们的源代码。是目前枯人接触过最优秀的一款基于jQuery的UI库,整体打包后不到300k, 几乎包含所有的常用组件。
jQuery UI vs EasyUI: 二者冲突怎么办?
很不幸,jQueryUI和EasyUI的某些组件是命名冲突的,如 Dialog, Tabs等,我们之前的项目主要是基于jQueryUI, 如果使用EasyUI将重写以前的代码,后来我们采取了一种折中的方案:
进入http://jqueryui.com/download 定制jQuery组件,只保留jQueryUI中的Tabs, Dialog. (其他的如DatatimePicker等使用EasyUI重写);这样我们会得到一个只有40K的jQueryUI文件,我们认为还是可以接受的。
将精简后的jQueryUI加载到EasyUI引用之后,这样EasyUI的Tabs和Dialog就会被复写。
91、jQuery和Zepto的区别?各自的使用场景?
(1) Zepto 对象 不能自定义事件
例如执行: $({}).bind('cust', function(){});
结果: TypeError: Object has no method 'addEventListener'
解决办法是创建一个脱离文档流的节点作为事件对象:
例如: $('').bind('cust', function(){});
(2)Zepto 的选择器表达式: [name=value] 中value 必须用 双引号 " or 单引号 ' 括起来
例如执行:$('[data-userid=123123123]')
结果:Error: SyntaxError: DOM Exception 12
解决办法: $('[data-userid="123123123]"') or $("[data-userid='123123123']")
2-1.zepto的选择器没有办法选出 $("div[name!='abc']") 的元素
2-2.zepto获取select元素的选中option不能用类似jq的方法$('option[selected]'),因为selected属性不是css的标准属性
应该使用$('option').not(function(){ return !this.selected })
比如:jq:$this.find('option[selected]').attr('data-v') * 1
zepto:$this.find('option').not(function() {return !this.selected}).attr('data-v') * 1
但是获取有select中含有disabled属性的元素可以用 $this.find("option:not(:disabled)") 因为disabled是标准属性
参考网址:https://github.com/madrobby/zepto/issues/503
2-3、zepto在操作dom的selected和checked属性时尽量使用prop方法,以下是官方说明:
(3)Zepto 是根据标准浏览器写的,所以对于节点尺寸的方法只提供 width() 和 height(),省去了 innerWidth(), innerHeight(),outerWidth(),outerHeight()
Zepto.js: 由盒模型( box-sizing )决定
jQery: 忽略盒模型,始终返回内容区域的宽/高(不包含 padding 、 border )解决方式就是使用 .css('width') 而不是 .width() 。
3-1.边框三角形宽高的获取
假设用下面的 HTML 和 CSS 画了一个小三角形:
[html] view plain copy
- <div class="caret"></div>
- .caret {
- width: 0;
- height: 0;
- border-width: 0 20px 20px;
- border-color: transparent transparent blue;
- border-style: none dotted solid;
- }
jQuery 使用 .width() 和 .css('width') 都返回 ,高度也一样;
Zepto 使用 .width() 返回 ,使用 .css('width') 返回 0px 。
所以,这种场景,jQuery 使用 .outerWidth() / .outerHeight() ;Zepto 使用 .width() / .height() 。
3-2.offset()
Zepto.js: 返回 top 、 left 、 width 、 height
jQuery: 返回 width 、 height
3-3.隐藏元素
Zepto.js: 无法获取宽高;
jQuery: 可以获取。
(4)Zepto 的each 方法只能遍历 数组,不能遍历JSON对象
(5)Zepto 的animate 方法参数说明 :详情点击->
zepto中animate的用法
(6)zepto的jsonp callback函数名无法自定义
(7)DOM 操作区别
jq代码:
[html] view plain copy
- (function($) {
- $(function() {
- var $list= $('<ul><li>jQuery插入</li></ul>', {
- id: 'insert-by-jquery'
- });
- $list.appendTo($('body'));
- });
- })(window.jQuery);
jQuery 操作 ul 上的 id 不会被添加。
zepto代码:
[html] view plain copy
- Zepto(function($) {
- var $list= $('<ul><li>Zepto插入</li></ul>', {
- id: 'insert-by-zepto'
- });
- $list.appendTo($('body'));
- });
Zepto 可以在 ul 上添加 id 。
(8)事件触发区别
jq代码:
[html] view plain copy
- (function($) {
- $(function() {
- $script= $('<script />', {
- src: 'http://cdn.amazeui.org/amazeui/1.0.1/js/amazeui.min.js',
- id: 'ui-jquery'
- });
- $script.appendTo($('body'));
- $script.on('load', function() {
- console.log('jQ script loaded');
- });
- });
- })(window.jQuery);
使用 jQuery 时 load 事件的处理函数 不会 执行
zepto代码:
[html] view plain copy
- Zepto(function($) {
- $script= $('<script />', {
- src: 'http://cdn.amazeui.org/amazeui/1.0.1/js/amazeui.js',
- id: 'ui-zepto'
- });
- $script.appendTo($('body'));
- $script.on('load', function() {
- console.log('zepto script loaded');
- });
- });
使用 Zepto 时 load 事件的处理函数 会 执行。
(9)zepto阻止事件冒泡
link传送门
10、zepto的slideUP和slidedown事件到底部才能触发
[html] view plain copy
- document.addEventListener('touchmove', function (event) {
- event.preventDefault();
- }, false);
92、Zepto的点透问题如何解决?
(1)“点透”是什么
你可能碰到过在列表页面上创建一个弹出层,弹出层有个关闭的按钮,你点了这个按钮关闭弹出层后后,这个按钮正下方的内容也会执行点击事件(或打开链接)。这个被定义为这是一个“点透”现象。
在前面的项目中遇到了如下图的问题:在点击弹出来的选择组件的右上角完成后会让完成后面的input输入框聚焦,弹出输入键盘,也就是点透了
(2)为什么会出现点透呢?
这个需要从zepto(或者jqm)源码里面看关于tap的实现方法:
View Code
可以看出zepto的tap通过兼听绑定在document上的touch事件来完成tap事件的模拟的,及tap事件是冒泡到document上触发的
再点击完成时的tap事件(touchstart\touchend)需要冒泡到document上才会触发,而在冒泡到document之前,用户手的接触屏幕(touchstart)和离开屏幕(touchend)是会触发click事件的,因为click事件有延迟触发(这就是为什么移动端不用click而用tap的原因)(大概是300ms,为了实现safari的双击事件的设计),所以在执行完tap事件之后,弹出来的选择组件马上就隐藏了,此时click事件还在延迟的300ms之中,当300ms到来的时候,click到的其实不是完成而是隐藏之后的下方的元素,如果正下方的元素绑定的有click事件此时便会触发,如果没有绑定click事件的话就当没click,但是正下方的是input输入框(或者select选择框或者单选复选框),点击默认聚焦而弹出输入键盘,也就出现了上面的点透现象。
(3)点透的解决方法:
方案一:来得很直接github上有个fastclick可以完美解决https://github.com/ftlabs/fastclick
引入fastclick.js,因为fastclick源码不依赖其他库所以你可以在原生的js前直接加上
1window.addEventListener( "load",function() {2FastClick.attach( document.body );3},false);
或者有zepto或者jqm的js里面加上
1$(function() {2FastClick.attach(document.body);3});
当然require的话就这样:
1 varFastClick = require('fastclick');2FastClick.attach(document.body, options);
方案二:用touchend代替tap事件并阻止掉touchend的默认行为preventDefault()
1$("#cbFinish").on("touchend",function(event) {2 //很多处理比如隐藏什么的3event.preventDefault();4});
方案三:延迟一定的时间(300ms+)来处理事件
1$("#cbFinish").on("tap",function(event) {2setTimeout(function(){3 //很多处理比如隐藏什么的4},320);5});
这种方法其实很好,可以和fadeInIn/fadeOut等动画结合使用,可以做出过度效果
理论上上面的方法可以完美的解决tap的点透问题,如果真的倔强到不行,用click
93、jQueryUI如何自定义组件?
如何开始使用
首先用$.widget()方法开始定义你的组件,它只接收三个参数:第一个是组件名称,第二个是可选的基类组件(默认的基类是$.Widget),第三个是组件的原型。
组件名称必须包含命名空间,要注意的是,官方组件的命名空间是以‘ui’开头的,比如:‘ui.tabs’。我在下面的用‘我’的拼音(‘wo’)。
$.widget("yourNamespace.yourWidgetName",[yourBaseWidget],yourWidgetPrototype)
$.Widget基类含有一个重要的属性‘options’,它用来定义公有参数,组件初始化时外部调用的参数会覆盖内部定义的参数;以及三个重要的私有的方法‘_create’、‘_init’、‘’,前两个相当于构造函数的作用,按顺序执行,_create()方法执行之后会触发'create'事件。 _trigger()方法会将参数中的指定函数标准化为W3C事件,并且触发这个自定义事件。
另外还有三个公有方法‘enable’,‘disable’,‘destroy’,分别表示启用、禁用和销毁组件。
这里很有意思的,是私有方法和公有方法的实现。jQuerUI Widget暴露的方法都是不以‘_’开头的:
// prevent calls to internal methods
if ( isMethodCall && options.charAt( 0 ) === "_" ) {
return returnValue;
}
实际上,jQueryUI Widget还是保留了原始的API,比如这样使用:
var $div = $('.demo:first');
var api = $div.data('divZoom');
// console.dir(api);
api.zoomIn();
//
对比
$div.divZoom('zoomIn');
一个实现完全私有变量的小技巧:
(function($) {
var privateVar = '';
$.widget("wo.divZoom",{});
})(jQuery)
所有代码
/*
* @by ambar
* @create 2010-10-20
* @update 2010-10-25
*/
(function ($) {
var html = '<div class="icon-zoom">\
<span title="zoom in" class="zoom-in">zoom in</span>\
<span title="zoom out" class="zoom-out">zoom out</span>\
</div>';
$.widget("wo.divZoom", {
_init: function () {
var self = this,
opt = self.options,
tgt = opt.target,
$el = self.element;
//
初始一次
if ($('div.icon-zoom', $el).length) return;
$el.append(html);
self.target = (tgt == '' ? $el : $el.find(tgt));
//
检测初始值
var level = self.target.attr(opt.dataPrefix);
self.target.attr(opt.dataPrefix, level || opt.level[0]);
self.btnZoomIn = $el.find('span.zoom-in').click($.proxy(self.zoomIn, self));
self.btnZoomOut = $el.find('span.zoom-out').click($.proxy(self.zoomOut, self));
},
destroy: function () {
this.element.find('div.icon-zoom').remove();
},
options: {
level : [120, 160, 200],
target : '',
speed : 'normal',
dataPrefix: 'data-zoom-level',
zooming : null,
select : null,
show : null
},
currentLevel: function () {
var self = this, opt = self.options, lvl = Number(self.target.attr(opt.dataPrefix));
return $.inArray(lvl, opt.level);
},
zoomIn: function () {
this.zoom(this.currentLevel() + 1);
},
zoomOut: function () {
this.zoom(this.currentLevel() - 1);
},
zoom: function (i) {
var self = this, opt = self.options, lvls = opt.level, $tgt = self.target;
if (i <= -1 || i >= lvls.length) return;
var value = lvls[i], originalValue = lvls[self.currentLevel()], style = { width : value, height: value };
var data = { target: $tgt, css: style, originalCss: { width : originalValue,height: originalValue } };
var goon = self._trigger('start', null, data);
if (!goon) return;
$tgt.animate(style, {
duration: opt.speed,
step: function (val) {
var css = { width: val, height: val };
self._trigger('zooming', null, $.extend({}, data, { css: css }));
},
complete: function () {
$tgt.attr(opt.dataPrefix, value);
self._trigger('stop', null, data);
}
});
}
});
})(jQuery)
在页面上调用
<script src="js/jquery-1.4.4.min.js"></script>
<script src="js/jquery.ui.widget.js"></script>
<!--
自定义的 -->
<script src="js/jquery.ui.wo.divZoom.js"></script>
<script type="text/javascript">
$(function () {
$('div.demo').divZoom({
target: '>a',
level: [80, 120, 160, 200],
zooming: function (e, ui) {
// console.log(e,ui.css);
},
start: function (e, ui) {
console.log('
开始', this, e.type, ui);
},
stop: function (e, ui) {
console.log('
结束', ui.css);
}
});
});
</script>
94、如何判断当前脚本运行在浏览器还是node环境中?(阿里)
node环境是一个服务器端js的解释器。
看this指向global还是指向window。
前者是node环境,后者是浏览器。即node全局变量是global,浏览器全局变量是window。
typeof window=="undefined"?global:window;
95、把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别?浏览器会如何解析它们?
(1)拉取 HTML 页面 (e.g. index.html)
(2)开始解析 HTML
(3)解析到 <script>
标签之后准备获取 script 文件.
(4)浏览器获取script文件。同时,html 解析中断并且阻断页面上其他html的解析。
(5)一段时间后,script下载完成并且执行。
(6)继续解析HTML文档的其他部分(解析script之后的html代码)
第4步导致了不好的用户体验,直到script文件全部下载完成之前HTML都不能得到解析。
- 移动端的点击事件的有延迟,为什么会有?
Google开发者文档中有提到:
mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.
移动浏览器为什么会设置300毫秒的等待时间呢?这与双击缩放的方案有关。平时我们有可能已经注意到了,双击缩放,即用手指在屏幕上快速点击两次,可以看到内容或者图片放大,再次双击,浏览器会将网页缩放至原始比例。
浏览器捕获第一次单击后,会先等待一段时间,如果在这段时间区间里用户未进行下一次点击,则浏览器会做单击事件的处理。如果这段时间里用户进行了第二次单击操作,则浏览器会做双击事件处理。这段时间就是上面提到的300毫秒延迟。
如何避免延迟
在特定场景如一些游戏页面,我们需要取消300毫毛的延迟。目前有以下方法:
方法一:静止缩放
[html] view plain copy
- <meta name="viewport" content="width=device-width user-scalable= 'no'">
使用这个方法必须完全禁用缩放来达到目的,虽然大部分移动端能解决这个延迟问题,但是部分苹果手机还是不行。
方法二:fastclick.js
FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到touchend事件的时候,会通过 DOM 自定义事件立即触发一个模拟click事件,并把浏览器在 300 毫秒之后真正触发的click事件阻止掉。使用方法如下。
第一步:在页面中引入fastclick.js文件。
第二步:在js文件中添加以下代码
在 window load 事件之后,在body上调用FastClick.attach()即可。
[javascript] view plain copy
- window.addEventListener(function(){
- FastClick.attach( document.body );
- },false);
如果你项目使用了JQuery,就将上面的代码改写成:
[javascript] view plain copy
- $(function() {
- FastClick.attach(document.body);
- });
方法三:指针事件
指针事件最初由微软提出,现已进入 W3C 规范的候选推荐标准阶段 (Candidate Recommendation)。指针事件是一个新的 web 事件系列,相应的规范旨在使用一个单独的事件模型,对所有输入类型,包括鼠标 (mouse)、触摸 (touch)、触控 (stylus) 等,进行统一的处理。
指针事件 (Pointer Events) 目前兼容性不太好,不知道在以后会不会更加支持。
- 知道各种JS框架(Angular, Backbone, Ember, React, Meteor, Knockout...)么? 能讲出他们各自的优点和缺点么?
angular、backbone、knockout都是完整的MV*框架
angular是双向数据绑定的,backbone、knockout是单向数据绑定的
React只是单纯地View层
98、解释JavaScript中的作用域与变量声明提升?
javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。
先看一段代码
1 2 3 4 5 |
var v = "hello"; (function(){ console.log(v); var v = "world"; })(); |
这段代码运行的结果是什么呢?
答案是:undefined
这段代码说明了两个问题,
第一,function作用域里的变量v遮盖了上层作用域变量v。代码做少些变动
1 2 3 4 5 |
var v = "hello"; if(true){ console.log(v); var v = "world"; } |
输出结果为”hello”,说明javascript是没有块级作用域的。函数是JavaScript中唯一拥有自身作用域的结构。
第二,在function作用域内,变量v的声明被提升了。所以最初的代码相当于:
1 2 3 4 5 6 |
var v = "hello"; (function(){ var v; //declaration hoisting console.log(v); v = "world"; })(); |
声明、定义与初始化
声明宣称一个名字的存在,定义则为这个名字分配存储空间,而初始化则是为名字分配的存储空间赋初值。
用C++来表述这三个概念
1 2 3 |
extern int i;//这是声明,表明名字i在某处已经存在了 int i;//这是声明并定义名字i,为i分配存储空间 i = 0;//这是初始化名字i,为其赋初值为0 |
javascript中则是这样
1 2 |
var v;//声明变量v v = "hello";//(定义并)初始化变量v |
因为javascript为动态语言,其变量并没有固定的类型,其存储空间大小会随初始化与赋值而变化,所以其变量的“定义”就不像传统的静态语言一样了,其定义显得无关紧要。
声明提升
当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明
1 2 3 4 5 6 |
(function(){ var a = "1"; var f = function(){}; var b = "2"; var c = "3"; })(); |
变量a,f,b,c的声明会被提升到函数作用域的最前面,类似如下:
1 2 3 4 5 6 7 |
(function(){ var a,f,b,c; a = "1"; f = function(){}; b = "2"; c = "3"; })(); |
请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:
1 2 3 4 5 6 7 8 9 |
(function(){ //var f1,function f2(){}; //hoisting,被隐式提升的声明 f1(); //ReferenceError: f1 is not defined f2(); var f1 = function(){}; function f2(){} })(); |
上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。
名字解析顺序
javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:
语言内置:所有的作用域中都有 this 和 arguments 关键字
形式参数:函数的参数在函数作用域中都是有效的
函数声明:形如function foo() {}
变量声明:形如var bar;
名字声明的优先级如上所示,也就是说如果一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,无论其在代码中的顺序如何。但名字的初始化却是按其在代码中书写的顺序进行的,不受以上优先级的影响。看代码:
1 2 3 4 5 6 7 8 9 |
(function(){ var foo; console.log(typeof foo); //function function foo(){} foo = "foo"; console.log(typeof foo); //string })(); |
如果形式参数中有多个同名变量,那么最后一个同名参数会覆盖其他同名参数,即使最后一个同名参数并没有定义。
以上的名字解析优先级存在例外,比如可以覆盖语言内置的名字arguments。
命名函数表达式
可以像函数声明一样为函数表达式指定一个名字,但这并不会使函数表达式成为函数声明。命名函数表达式的名字不会进入名字空间,也不会被提升。
1 2 3 4 5 |
f();//TypeError: f is not a function foo();//ReferenceError: foo is not defined var f = function foo(){console.log(typeof foo);}; f();//function foo();//ReferenceError: foo is not defined |
命名函数表达式的名字只在该函数的作用域内部有效。
===
在认识一切事物之后,人才能认识自己,因为事物仅仅是人的界限。 —— 尼采
Js作用域与作用域链详解
http://blog.csdn.net/yueguanghaidao/article/details/9568071
一直对Js的作用域有点迷糊,今天偶然读到Javascript权威指南,立马被吸引住了,写的真不错。我看的是第六版本,相当的厚,大概1000多页,Js博大精深,要熟悉精通需要大毅力大功夫。
一:函数作用域
先看一小段代码:
[javascript] view plaincopy
var scope="global";
function t(){
console.log(scope);
var scope="local"
console.log(scope);
}
t();
(PS: console.log()是firebug提供的调试工具,很好用,有兴趣的童鞋可以用下,比浏览器+alert好用多了)
第一句输出的是: "undefined",而不是 "global"
第二讲输出的是:"local"
你可能会认为第一句会输出:"global",因为代码还没执行var scope="local",所以肯定会输出“global"。
我说这想法完全没错,只不过用错了对象。我们首先要区分Javascript的函数作用域与我们熟知的C/C++等的块级作用域。
在C/C++中,花括号内中的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的。而Javascript压根没有块级作用域,而是函数作用域.
所谓函数作用域就是说:-》变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
所以根据函数作用域的意思,可以将上述代码重写如下:
[javascript] view plaincopy
var scope="global";
function t(){
var scope;
console.log(scope);
scope="local"
console.log(scope);
}
t();
我们可以看到,由于函数作用域的特性,局部变量在整个函数体始终是由定义的,我们可以将变量声明”提前“到函数体顶部,同时变量初始化还在原来位置。
为什么说Js没有块级作用域呢,有以下代码为证:
[javascript] view plaincopy
var name="global";
if(true){
var name="local";
console.log(name)
}
console.log(name);
都输出是“local",如果有块级作用域,明显if语句将创建局部变量name,并不会修改全局name,可是没有这样,所以Js没有块级作用域。
现在很好理解为什么会得出那样的结果了。scope声明覆盖了全局的scope,但是还没有赋值,所以输出:”undefined“。
所以下面的代码也就很好理解了。
[javascript] view plaincopy
function t(flag){
if(flag){
var s="ifscope";
for(var i=0;i<2;i++)
;
}
console.log(i);
console.log(s);
}
t(true);
输出:2 ”ifscope"
二:变量作用域
还是首先看一段代码:
[javascript] view plaincopy
function t(flag){
if(flag){
s="ifscope";
for(var i=0;i<2;i++)
;
}
console.log(i);
}
t(true);
console.log(s);
就是上面的翻版,知识将声明s中的var去掉。
程序会报错还是输出“ifscope"呢?
让我揭开谜底吧,会输出:”ifscope"
这主要是Js中没有用var声明的变量都是全局变量,而且是顶层对象的属性。
所以你用console.log(window.s)也是会输出“ifconfig"
当使用var声明一个变量时,创建的这个属性是不可配置的,也就是说无法通过delete运算符删除
var name=1 ->不可删除
sex=”girl“ ->可删除
this.age=22 ->可删除
三:作用域链
先来看一段代码:
[javascript] view plaincopy
name="lwy";
function t(){
var name="tlwy";
function s(){
var name="slwy";
console.log(name);
}
function ss(){
console.log(name);
}
s();
ss();
}
t();
当执行s时,将创建函数s的执行环境(调用对象),并将该对象置于链表开头,然后将函数t的调用对象链接在之后,最后是全局对象。然后从链表开头寻找变量name,很明显
name是"slwy"。
但执行ss()时,作用域链是: ss()->t()->window,所以name是”tlwy"
下面看一个很容易犯错的例子:
[html] view plaincopy
<html>
<head>
<script type="text/javascript">
function buttonInit(){
for(var i=1;i<4;i++){
var b=document.getElementById("button"+i);
b.addEventListener("click",function(){ alert("Button"+i);},false);
}
}
window.οnlοad=buttonInit;
</script>
</head>
<body>
<button id="button1">Button1</button>
<button id="button2">Button2</button>
<button id="button3">Button3</button>
</body>
</html>
当文档加载完毕,给几个按钮注册点击事件,当我们点击按钮时,会弹出什么提示框呢?
很容易犯错,对是的,三个按钮都是弹出:"Button4",你答对了吗?
当注册事件结束后,i的值为4,当点击按钮时,事件函数即function(){ alert("Button"+i);}这个匿名函数中没有i,根据作用域链,所以到buttonInit函数中找,此时i的值为4,
所以弹出”button4“。
四:with语句
说到作用域链,不得不说with语句。with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。
看下面代码
[javascript] view plaincopy
person={name:"yhb",age:22,height:175,wife:{name:"lwy",age:21}};
with(person.wife){
console.log(name);
}
with语句将person.wife添加到当前作用域链的头部,所以输出的就是:“lwy".
with语句结束后,作用域链恢复正常。
99、哪些操作会造成内存泄漏?
Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的可能是24M,当我们的内存占用超过了一定的程度后,就会出现OutOfMemory的错误。
下面说明几点可能导致内存泄露的原因,供大家参考。
(1)对象内存过大
保存了多个好用内存过大的对象,造成内存超出限制。
(2)资源释放
程序代码的问题,长期保持某些资源,如Context,Cursor,IO流的引用,资源得不到释放造成内存泄露。
(3)static关键字的使用
static 是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例,就可能会造成内存的泄露。
针对static的解决方案:
应该尽量避免static成员变量引用资源耗费过多的实例,比如Context.
Context尽量使用ApplicationContext的生命周期比较长,引用它不会出现内存泄露。
使用WeakReference代替强引用。比如可以使用WeakReference<Context> mContext;
(4).线程导致内存溢出
线程产生内存泄露的主要原因在于线程生命周期的不可控。如当我们切换横竖屏的时候,一般会重新创建Activity,老的Activity应该被销毁。但是此时我们在子线程中正在进行耗时的操作,老的Activity不会被销毁,这个时候就会出现内存泄露。
解决方案:
将线程的内部类,改为静态内部类。
在线程内部采用弱引用保存Context引用。
100、Node.js的适用场景?
NodeJS是近年来比较火的服务端JS平台,这一方面得益于其在后端处理高并发的卓越性能,另一方面在nodeJS平台上的npm、grunt、express等强大的代码与项目管理应用崛起,几乎重新定义了前端的工作方式和流程。
NodeJS的成功标志着它的强大,但是不是所有情况都适合应用NodeJS作为服务器端平台呢?
答案当然是否定的,而网上也是众说纷纭。那我们从原理出发了解一下NodeJS的适用情况。
在讲NodeJS之前我们不仿先看一下传统(以Apache为代表)的服务器端处理平台处理并发的方式。
(1) Apache的多线程高并发模式
Apache是当前世界排名第一的Web服务端软件,它由于支持多线程并发而受到广大服务器技术选型者的欢迎。但发展到后来,Apache在一些WEB的大型应用中也渐渐暴露出它的缺点:阻塞。
那有的同学会奇怪,Apache不是多线程处理并发吗,为什么还会出现阻塞呢?
要明白这一点我们首先需要了解线程这个概念
1.1 什么是线程?
我们引用官方的解释:线程可以独立运行的最小的CPU单位,可以在同一个进程里并发运行,共享该进程下的内存地址空间(注意这个特点)。
我们可以看到同一个进程下的线程是会共享相同的文件和内存的(内存地址空间),所以大家可以想象,当不同的线程需要占用同一个变量时,根据先到先得的原则,先到的线程在运作时,后来的线程只能在旁边等待,也就是加入到了阻塞排队序列。所以这就是造成线程阻塞的原因。
因此,虽说进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,而且它们从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,因为程序设计者必须小心,确保它们不会妨碍同一进程里的其它线程。
了解了多线程并行的缺陷后,我们就可以更好地理解NodeJS的强大所在了。因为NodeJS是异步单线程的!
(2) NodeJS的异步I/O原理
我们先来看一段Apache请求数据库的代码:
代码执行到第一行的时候线程会阻塞,等待query返回结果,然后继续处理。由于数据库查询、磁盘读写、网络通信等原因(所谓的I/O)阻塞时间会非常大(相对于CPU始终频率)。对于高并发的访问,一方面线程长期阻塞等待,另一方面为了应付新情求而不断添加新线程,会浪费大量系统资源,同时线程的增加也会也会占用大量的CPU时间来处理内存上下文切换。看看node.js怎么处理。
看到没,就四个字:异步回调。query的第二个参数是一个回调函数,进程执行到db.query的时候不会等待结果返回,而是直接继续执行下面的语句,直到进入事件循环。当数据库执行结果返回的时候会将事件发送到事件队列,等到线程进入事件循环后才会调用之前的回调函数。更专业的说法是异步I/O。只要单线程就可以。
那为什么NodeJS做到单线程,却可以实现异步呢?在这里我们先上一幅图,直戳图中的Event queue
看到没,NodeJS的工作原理其实就是事件循环。可以说每一条NodeJS的逻辑都是写在回调函数里面的,而回调函数都是有返回之后才异步执行的!
看到这里,你不禁会惊叹,NodeJS如果所有处理都异步,岂不是晓得飞了?错错错!当然不是,不要忘记,NodeJS实现这些的基础是单线程。没错,单线程!一条线程扛起所有操作!
你可以想象一下,NodeJS在寒风中面对着10万并发大军,OK,没问题,上来敌人一个扔到城里,上来一个又扔到城里。城里全民皆兵,可以很好地消化这些敌人。但如果上来一个类似于张飞赵云这样的人物,老Node心里一惨,和张飞大战300回合,把他打残了,再扔到城里。那后面的10万大军就得等这300回合。。。
所以这说明什么?说明NodeJS不是没有阻塞,而是阻塞不发生在后续回调的流程,而会发生在NodeJS本身对逻辑的计算和处理。我们已经知道,NodeJS的分发能力无比强大,可以循环事件进行异步回调。但如果在循环事件时遇到复杂的逻辑运算,那么单薄的单线程怎么支撑得起上百万的逻辑+并发呢?NodeJS它的所有I/O、网络通信等比较耗时的操作,都可以交给worker threads执行再回调,所以很快。但CPU的正常操作,它就只能自己抗了。
说到这里,各位对NodeJS的特性估计也大概有个谱了。所以说适用的场景基本是呼之欲出了~!
(3) NodeJS的应用场景
既然NodeJS处理并发的能力强,但处理计算和逻辑的能力反而很弱,因此,如果我们把复杂的逻辑运算都搬到前端(客户端)完成,而NodeJS只需要提供异步I/O,这样就可以实现对高并发的高性能处理。情况就很多啦,比如:RESTFUL API、实时聊天、客户端逻辑强大的单页APP,具体的例子比如说:本地化的在线音乐应用,本地化的在线搜索应用,本地化的在线APP等。
顺便提一下Apache,打压了这么多,给颗甜枣。Apache由于其多线程高并发共享内存地址空间的特性,那就意味着如果服务器足够强大,处理器足够高核,Apache的运作将会非常良好,所以适用于(并发)异步处理相对较少,后台计算量大,后台业务逻辑复杂的应用程序。
- 简述一下 Handlebars 的基本用法?
Handlebars的安装是比较简单和方便的;handlebars是一个纯JS库,因此你可以像使用其他JS脚本一样用script标签来包含handlebars.js
<scriptsrc="jquery.min.js"></script><scripttype="text/javascript"src=".js/handlebars.js"></script>
基本
html:
<--模板 --><script type="text/x-handlebars-template"id="tpl"> {{#each}}...{{/each}}</script>
js:
//获取到模板var tpl = $("#tpl").html();//预编译模板var template = Handlebars.compile(tpl);//模拟数据(也可以是获取的json数据)var context = {};//匹配数据var html = template(context);//输入模板$('body').html(html);
注 : 这是handlebars最常用的一中创建使用模式。
- 用js实现千位分隔符?
输入:数字(考虑数字是否合法、正负号、小数点)、字符串
输出:考虑到使用场景,最好是字符串
测试用例:-1234567.9012
期待输出:-1,234,567.9012
千位分隔符貌似在《精通正则表达式》中讲环视的时候作为经典范例,然而写出来发现js不支持逆序环视,也就是 (?<=expression) (?<!expression) 这两种是不支持的。
// 正则function thousandBitSeparator(num) {
return num && num
.toString()
.replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
return $1 + ",";
});}console.log(thousandBitSeparator(-1234567.9012));// -1,234,567.9012
todo
当测试用例是1000的时候,此正则不能正确标注千位分隔符,现修改如下:
function thousandBitSeparator(num) {
return num && (num
.toString().indexOf('.') != -1 ? num.toString().replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
return $1 + ",";
}) : num.toString().replace(/(\d)(?=(\d{3}))/g, function($0, $1) {
return $1 + ",";
}));}console.log(thousandBitSeparator(1000));//1,000
103、检测浏览器版本版本有哪些方式?
如何判断浏览器的类型和版本? -- 使用JavaScript的内置对象 navigator 的属性userAgent的值来判断(navigator.userAgent)。
navigator是javascript的内置对象,通常用于检测浏览器与操作系统的版本。 常用的属性有
- appCodeName -- 浏览器代码名的字符串表示
- appName -- 官方浏览器名的字符串表示
- appVersion -- 浏览器版本信息的字符串表示
- cookieEnabled-- 如果启用cookie返回true,否则返回false
- javaEnabled -- 如果启用java返回true,否则返回false
- platform -- 浏览器所在计算机平台的字符串表示
- plugins -- 安装在浏览器中的插件数组
- taintEnabled -- 如果启用了数据污点返回true,否则返回false
- userAgent-- 用户代理头的字符串表示(就是包含浏览器版本信息等的字符串)
104、我们给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡,你来说下会执行几次事件,然后会先执行冒泡还是捕获
事件的执行顺序绝对是让人头疼的问题。当父元素与子元素都绑定了多个事件,且有的绑定在冒泡阶段、有的绑定在捕获阶段时,事件的触发顺序如何?如果你只关心这个问题,请直接下滑到3. 绑定多个事件,且由用户行为触发。如果你想细致了解JavaScript中的事件发生,请慢慢阅读。
(1) 原生事件的发生顺序
一般来讲,当为一个a标签添加click事件以后,点击这个标签,会先执行绑定的事件、后跳转页面。一个input绑定blur事件以后,你在input里输入完内容,点击提交按钮,会先发生blur事件,后发生click事件。当然,这是一般来讲。我在一个React项目中曾经发生表单提交时,先发生click事件,blur事件没有来得及发生,造成表单内容没有检验就提交到后台,原因我至今没有找到,解决办法是在click事件上加一个50ms的延迟。
(2)自定义事件
JavaScript中也支持手动触发事件,请看下面代码。
a.addEventListener(
'click',
function(){
console.log(input.value);
console.log(
this.getAttribute(
'href'));
console.log(location.href);
},
false);
//a是我已经通过id获得好的一个a标签
var
event = document.createEvent(
'HTMLEvents');
// initEvent接受3个参数: 事件类型,是否冒泡,是否阻止浏览器的默认行为
event.initEvent(
'click',
true,
true);
event.eventType =
'click';
//触发a上绑定的自定义事件
a.dispatchEvent(event);
//注:jQuery中有更简单的trigger()方法实现自定义事件功能
JavaScript中自定义事件的类型有(即document.createEvent('HTMLEvents')
中的参数):
UIEvents:一般化的UI事件。
MouseEvents:一般化的鼠标事件。
MutationEvents:一般化的DOM变动事件。
HTMLEvents:一般化的HTML事件。
自定义事件的发生比较容易控制,你什么时候触发(dispatchEvent/fireEvent)它,它就什么时候发生。
(3)绑定多个事件,且由用户行为触发
这个情况最复杂,也是标题中的情况:父元素与子元素都绑定多个事件,且有的事件在捕获阶段、有的事件在冒泡阶段。
下面这个例子,父元素div绑定两个事件(一个冒泡阶段、一个捕获阶段),子元素也是这种情况。事件触发顺序如何。
var
btn = document.querySelector(
'button');
var
div = document.querySelector(
'div');
btn.addEventListener(
'click',
function(){
console.log(
'bubble',
'btn');
},
false);
btn.addEventListener(
'click',
function(){
console.log(
'capture',
'btn');
},
true);
div.addEventListener(
'click',
function(){
console.log(
'bubble',
'div');
},
false);
div.addEventListener(
'click',
function(){
console.log(
'capture',
'div');
},
true);
执行结果:
乍一看这个结果有些乱,但仔细分析可以得出结论:
绑定在被点击元素的事件是按照代码顺序发生,其他元素通过冒泡或者捕获“感知”的事件,按照W3C的标准,先发生捕获事件,后发生冒泡事件。所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件 。
105、设计模式 知道什么是singleton, factory, strategy, decrator么?
设计模式主要分三个类型:创建型、结构型和行为型。 其中创建型有: 一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。 三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。 五、Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。 行为型有: 六、Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。 七、Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。 八、Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。 九、Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。 十、State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。 十一、Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。 十二、China of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系 十三、Mediator,中介者模式:用一个中介对象封装一些列的对象交互。 十四、Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。 十五、Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 十六、Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 结构型有: 十七、Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。 十八、Facade,外观模式:为子系统中的一组接口提供一致的界面,fa?ade提供了一高层接口,这个接口使得子系统更容易使用。 十九、Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问 二十、Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。 二十一、Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。 二十二、Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。 二十三、Flyweight,享元模式
106、常使用的库有哪些?
使用率较高的框架有jQuery、YUI、Prototype、Dojo、Ext.js、Mootools等。
- 列举IE与其他浏览器不一样的特性?
事件不同之处:
触发事件的元素被认为是目标(target)。而在 IE 中,目标包含在 event 对象的 srcElement 属性;
获取字符代码、如果按键代表一个字符(shift、ctrl、alt除外),IE 的 keyCode 会返回字符代码(Unicode),DOM 中按键的代码和字符是分离的,要获取字符代码,需要使用 charCode 属性;
阻止某个事件的默认行为,IE 中阻止某个事件的默认行为,必须将 returnValue 属性设置为 false,Mozilla 中,需要调用 preventDefault() 方法;
停止事件冒泡,IE 中阻止事件进一步冒泡,需要设置 cancelBubble 为 true,Mozzilla 中,需要调用 stopPropagation();
- WEB应用从服务器主动推送Data到客户端有那些方式?
html5
提供的Websocket
不可见的iframe
WebSocket
通过Flash
XHR
长时间连接
XHR Multipart Streaming
<script>
标签的长时间连接(可跨域)
- 你有用过哪些前端性能优化的方法?
(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
(4) 当需要设置的样式很多时设置className而不是直接操作style。 (5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作
(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
(7) 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳
(8) 避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示比div+css布局慢。
对普通的网站有一个统一的思路,就是尽量向前端优化、减少数据库操作、减少磁盘IO。向前端优化指的是,在不影响功能和体验的情况下,能在浏览器执行的不要在服务端执行,能在缓存服务器上直接返回的不要到应用服务器,程序能直接取得的结果不要到外部取得,本机内能取得的数据不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询。减少数据库操作指减少更新次数、缓存结果减少查询次数、将数据库执行的操作尽可能的让你的程序完成(例如join查询),减少磁盘IO指尽量不使用文件系统作为缓存、减少读写文件次数等。程序优化永远要优化慢的部分,换语言是无法“优化”的
110、new操作符具体干了什么呢
- 先创建了一个新的空对象
(2)然后让这个空对象的__proto__
指向函数的原型prototype
(3)将对象作为函数的this传进去,如果return 出来东西是对象的话就直接返回 return 的内容,没有的话就返回创建的这个对象
前端学习--js.2相关推荐
- 前端学习——JS基础知识点复习
一. JS复习 1.1 如何使用JS HTML标签内使用JS,要求写在onclick等事件属性或者href属性中(不推荐使用) 页面中的script标签内可以直接写JS代码 script标签的src属 ...
- 面向面试题的前端学习-js篇(自用,持续完善中)
前言:初心是记录面试题,慢慢由每个知识点引伸出去,逐渐查缺补漏,构建出更完善的前端知识系统. 题目来源:牛客网 gitnub 目录 HTTP协议 get请求传参长度的误区 补充get和post请求在缓 ...
- 前端学习JS第八天(P102--P110)
1.创建元素节点document.createElement(),创建文本节点document.createTextNode(),父节点.appendChild()向一个父节点添加一个新的子节点 2. ...
- 前端学习---JS高级教程
文章目录 JS对象 创建对象的三种方式 内置对象 Math对象 Date对象 数组对象 字符串对象 JS对象 JS中所有事物都是对象.字符串.数值.数组.函数.布尔型.数字型.日期.数学和正则表达式都 ...
- 前端学习JS第七天(P90--P101)
1.DOM,文档对象模型,document object model,在js中通过dom操作网页.文档就指整个html网页,对象就是将网页每一个部分都转换成对象,模型用来表示对象之间的关系. 2.网页 ...
- js怎么在一个div中嵌入另一网站_好程序员web前端学习路线分享HTML5常见面试题集锦一...
好程序员web前端学习路线分享HTML5常见面试题集锦,接下来将会持续为大家分享几篇HTML5常见面试题. 1.布局 左边20% 中间自适应 右边200px 不能用定位 答案:圣杯布局/双飞翼布局或者 ...
- 【前端学习笔记】JavaScript + jQuery + Vue.js + Element-UI
前端学习笔记 JavaScript jQuery Vue.js Element-UI Java 后端部分的笔记:Java 后端笔记 JavaScript 基础语法(数据类型.字符串.数组.对象.Map ...
- web前端学习基础教程,简单的图片旋转木马自动轮播js代码
一款简单的图片旋转木马自动轮播js代码,图片叠加轮播切换效果,支持点击左右箭头按钮控制切换. 案例效果图 案例源码: <!DOCTYPE html> <html lang=" ...
- 前端学习笔记(js基础知识)
前端学习笔记(js基础知识) JavaScript 输出 JavaScript 数据类型 常见的HTML事件 DOM 冒泡与捕获 流程控制语句 for..in 计时器 let,var,const的区别 ...
最新文章
- 写代码:使用while循环实现输出1,2,3,4,5,7,8,9,11,12
- Nature:科研PUA太严重,过半博士后打算逃离
- 【数据结构】平衡树 - treap
- LInux CentOS6 无人值守安装实例(原作)
- 三维重建:闭环检测-相机闭环
- 每日一笑 | 最真实的商业模式
- Spring Cloud Config 规范
- csv文件怎么转成excel_Python操作Excel文件(1):花式大师pyexcel
- python与西门子1200通讯_西门子S7-1200的以太网通信
- 透视特洛伊木马程序开发技术(转)
- EPS电动转向系统分析
- 使用js正则表达式验证
- html横向滚动字幕代码,js文字横向滚动特效
- 用命令启动java我的世界_我的世界Minecraft Mod开发学习笔记 - 实现一个简单的命令Mod...
- 日式卡通渲染的效果的unity实现
- 什么是大数据?大数据的特点?
- mac安装Homebrew报443
- 记成功安装win10+elementary双系统
- Spring--官方文档部分翻译(第五章 面向Aspect的编程-AOP)
- SK海力士拟2022年后投资千亿美元新建4座半导体工厂