前面说了说了js的相关知识,基本上除了语法外,把项目常用的知识做了一个梳理,现在说下js的其它方面的知识,这些知识不成体系,属于不理解对于一般开发没什么太多影响,但如果理解清楚,可以更好去开发。
js解析引擎:
-
引擎的定义:
- 什么是js解析引擎?简单的说是就能够读懂javascript代码的的平台,如你写一段代码 var a=1;var b=1;var c=a+b;引擎做的事情就这一段代码执行成我们想要的结果,这就是引擎要做的事情。 上面据说的和C/C中的编译过程很像,但是js和C/C有所不同,他们的编译器是把源代码转成另外一种代码(如机器码),而js中是直接解析并把代码结果给运算出来。 但是现在也无法完全这样定义,在chrome的V8引擎里面,为了提高js的提高效率,会在执行之前把js编译成机器代码。这个问题大可不用过于纠结。
-
js语言的标准:
- 语言都有一个标准,对于js也是这样,如果想深入了解这js可以阅读下ECMASCript,这里面是原汁原味的js的语言标准,不过这个不用太过于着急,只要把基础学会了,至于标准嘛,不过只是拿来参考和提高编码质量而已。当然js的引擎也是程序,也是由程序编写而来(chrome v8的引擎就是由C/C++),如果你能力很高,可以直接看看引擎的源码。
-
浏览器与js引擎:
- 浏览器与js引擎关系,这个很好理解,js引擎是浏览器的一个组成部分,浏览器做的事情很多,执行js也是一个功能。当浏览器从服务器上面请求到页面信息时,就根据自身的特性去解析页面和运行脚本。
js’小坑’注意:
-
var的使用:
-
var a=b=1;这个代码看着没有问题,但是这个b却不小心变成了全局变量,使用中请切记,如果想定义多个变量,可以 写成 var a=1,b=1;看代码:
function t(){ var a=b=1; console.log(a); } t(); console.log(window.a); console.log(window.b)
从上面的结果可以看出,这个变量b,已经成为了一个全局变量,这样的使用,无论对于什么语言都是一个大忌。 -
全局变量和隐性全局变量
到这里可能会有一个疑问,代码如下:var a=1; b=1; function t(){ console.log(a); console.log(b); }
这里的a和b有什么区别?a是全局变量,那b呢?在这里纠证我原来所说有全局变量,其实b是一个隐性的全局变量,并不是真正的全局变量,用delete 做个测试:
delete window.a;//false delete window.b;//true
从上面的结果可以看出,真正的声明的变量是无法用delete 删除,而隐性的可以的。
-
-
for循环:
-
for(var i=0;i<arr.length;i++){...}
这段代码估计是很多人经常写,但是这样会导致arr获得长度执行了很多次,优化如下:for(var i=0,len=arr.length;i<len;i++){....}
这样多命名一个变量把数组的长度’缓存’下来,这样只需要一次获取就行了
同时还可以再优化:1、不要用i++,用i+=1或i=i+1替换,这样会造成解析的难度 2、让数字和0相比,效率会更快
修改如下:for(var len=arr.length;len>0;len=len-1){....}
-
-
for..in的使用:
- for..in..这个主要是在遍历对象属性的时候使用,看代码:
function funcA() { this.name = "A"; this.show = function() { console.log(this.name); } } function funcB() { this.age = 50; this.read = function() { console.log(this.age); } } funcB.prototype = new funcA(); var b = new funcB(); for (var p in b) { console.log(p); }
从上面的运行结果可以看出,这个输出把继承到的属性也输出了,在某些情况下并不是我们想要的,如果继承的属性过多,在遍历的情况下肯定会对性能有很大的影响,可以考虑hasOwnProperty属性,把不需要的属性从原型链上面去掉,so代码可以改成下面的形势:var b = new funcB(); for (var p in b) { if (b.hasOwnProperty(p)) console.log(p); }
下面对于这个再进行下扩展(纯属娱乐,不推荐这样的写法,不过可以帮助我们理解前面所学的知识)for (var p in b) { if(Object.prototype.hasOwnProperty.call(b,p)) console.log(p); }
至于为什么这样可以写,可以参考下前面的文章,这里不多说,如果嫌这样写代码比较长,也可用一个变量把这个函数给‘缓存’下来。
- for..in..这个主要是在遍历对象属性的时候使用,看代码:
-
谨慎eval(),setTimeout,setInterval和Function的使用:
-
好用?误用?隐患?
对于这几个函数来说可能都不陌生,基本上在项目中处处可以见到,对于eval()这个函数来说,他可以接受任意的字符,把他当成js的代码来运行,如:var obj={}; obj.title="javascript"; var p="title"; eval("alert(obj."+p+")"); //应该使用的替代方法 alert(obj[p]);
可以看出eval的功能是很强大,但是同时也带来了很安全的漏洞,我想很多人都用过Ajax从后台获得数据,然后利用这个函数转成json格式,这个时候最好用浏览器自带的JSON.parse方法,如果浏览器不支持,可以考虑从后台转成json对象后再返回到前台,如果上面的两种方法都不可行,可以使用Json.org相关的库。
-
用Function的替换:
如果在某些地方不得不使用eval()的话,可以考虑使用new Function()替代。因为在使用的过程中eval()会对全局的作用域会有污染,看代码:console.log(typeof a); console.log(typeof b); var jsstring='var a=1;console.log(a);'; eval(jsstring); jsstring="var b=2;console.log(b);"; new Function(jsstring)(); console.log(typeof a); console.log(typeof b);
从上面的图可以看出,虽然结果一样,但eval()运行后的代码的变量a把全局变量污染了,而new Function()把字符作为一个函数的内部的局部变量处理。当然上面使用的eval()也可以修改下,正如前面说的匿名函数,把eval()再次封装下,这里也是娱乐下,不推荐使用,如:(function(){ eval(jsstring); }());
setTimeout,setIntervalp这两个函数和eval的函数传递相同,如下:
function funcA(){ console.log("hello"); } setTimeout("funcA();",1000); setInterval("funcA();",1000); //修改成下面的方式 setTimeout(funcA,1000); setInterval(funcA,1000);
-
好用?误用?隐患?
-
对象都是引用类型:
- 如题,如果想仅仅使用值,要采用复制属性的办法了
var a={}; var b=a; a.id=1; console.log(b.id);//1
- 如题,如果想仅仅使用值,要采用复制属性的办法了
说说function 和arguments
- 说说arguments
function是js的函数声明,arguments是参数列表。在函数被调用的时候成生成的一个对象,这个对象保留了当前被调用函数的参数,并生成属性callee(被调用函数)指向自身。先看下面的代码:
首先看下代码:
function funcA(age, name) {
console.log(arguments);
}
function funcB() {
console.log(arguments);
funcA(18, "wells");
}
funcB();
上面的输出结果可以明显看出当前argumets里面的属性和数据,至于为什么,下面会再说到。
-
说说callee和caller
本来不想说这两个东西,因为写这几个系列的文章是为了对js有一个入门的概念就行了,但是这篇博客的目的就是为了说明其它的一些七七八八的东西。所以对于这个概念,还是说说为好,以免以后再想说,也没有这个心力了。
关于这个概念要想更好的去理解,就要知道下js的工作原理,对于js来说,只是单线程的,代码的运行只是把要运行的代码放到一个队列里面去执行(setTimeout和setInterval,这两个函数是可以把函数的对象插入到队列里面,以获得优先执行的权利),同时每一种代码执行都需要上下文里面的变量和对象。如一个函数的调用,可能会引用到其它的变量,同样它也可以再次调用其它的函数。当一个上下文激活了另一个上下文的时候,调用者称为caller,被调用者称为callee.当然递归调用的时候 caller和callee是一个函数。
当一个caller激活了一个callee,那么这个caller就会暂停自身的执行,把当前的执行权利交给callee,当这个callee运行完之后再控制权交给caller继续向下执行。 -
caller和callee使用事例
关于这两个的使用很少,下面我就给一个callee的使用事例,用callee写一个递归,计算斐波那次数列,供参考:function funcA(n) { if (n == 1 || n == 2) { return 1; } else { //无非是改下名字而已 return arguments.callee(n - 1) + arguments.callee(n - 2); } } console.log(funcA(10));
编程规范:
-
缩进
在代码中没有缩进的代码看起来非常的糟糕,现在的js的代码编辑器都有一个代码缩进的功能,这个就不多说了 -
大括号{}
- if和for:
关于if和for后面只有一句代码,要不要添加大括号?我的答案是:要的!因为你现在看到括号里面只有一句,如果后面再添加,或者有更新了,所以为了长远的打算,还要要加上;
- if和for:
-
命名规范
命名规范的事情到不用怎么去说了,网上有一大堆的资料,这里只要注意两点就行:- 1、构造函数首字母要大写
- 2、一般函数对象首字母小写
这样的好处就是能够看到函数的时候我能不能直接用new 去构造新的对。
```js
//构造函数
function Dog(){
}
//普通函数
function show(){}
```总结:
到目前为止,js方面的基础知识已经说完了,下篇会整理一些jQuery方面的快速学习的知识,把相关选择器、dom操作、缓存方面的知识快速说下,后面会着重说下jQuery的插件开发(这个才是重点),后面会把平时写的插件做一个分享。
写于 2015.11.21完
第24篇 js小知识和“坑”的更多相关文章
-
第十九篇 js高级知识---词法分析和AO 链
上面一篇文章说了js的作用域链,这一节算是对上面的延申,有一个典型的例子,首先看原来的一段代码: var name = "test"; function t() { var b = ...
-
零散的JS和node.js小知识
JS的连续赋值和曾经出现的怪异情况 let a=1; let b=a=3; 如上的真实赋值过程 => a=1 => a=3 => b=3 => 一般来说,等号是从右向左赋值的 ...
-
javascript实用技巧,js小知识
一.js整数的操作 使用|0和~~可以将浮点转成整型且效率方面要比同类的parseInt,Math.round 要快,在处理像素及动画位移等效果的时候会很有用.性能比较见此. var foo = (1 ...
-
第20篇 js高级知识---深入原型链
前面把js作用域和词法分析都说了下,今天把原型链说下,写这个文章费了点时间,因为这个东西有点抽象,想用语言表达出来不是很容易,我想写的文章不是简单的是官方的API的copy,而是对自己的知识探索和总结 ...
-
第十八篇 js高级知识---作用域链
一直有想法去写写js方面的东西,我个人是最喜欢js这门语言,喜欢的他的*和强大,虽然作为脚本语言有很多限制的地方,但也不失为一个好的语言,尤其是在H5出现之后.下面开始说说js的方面的东西,由于自己 ...
-
js 小知识
在iframe 页面获取父级页面的 html var obj = window.parent.document.getElementById('modaliframe'); 解决Jquery 的在一个 ...
-
看到的一些js小知识
向数组结尾添加元素高效方法: var arr = [1,2,3]; arr[arr.length] = 4 头部: var a = [1,2,3]; a.concat(4,5); // 1,2,3,4 ...
-
angular.js小知识总结
angular-watch.html 代码如下: <script> var app = angular.module('app',[]); app.controller('ctrl',fu ...
-
js小知识-数组去重
查看zepto源码时,看到它的数组去重写法非常简单.下面是代码 var uq = function(array){ return [].filter.call(array,function(item, ...
随机推荐
-
浅谈WeakHashMap
Java WeakHashMap 到底Weak在哪里,它真的很弱吗?WeakHashMap 的适用场景是什么,使用时需要注意些什么?弱引用和强引用对Java GC有什么不同影响?本文将给出清晰而简洁的 ...
-
[原]我在Windows环境下的首个Libevent测试实例
libevent对Windows环境也有很好的支持,不过初次学习和编译libevent简单实例,总是有一些陌生感的,只有成功编译并测试了一个实例,才会有恍然大悟的感觉.下面将要讲到的一个实例是我从网上 ...
-
.NET设计模式(3):抽象工厂模式(Abstract Factory)(转)
概述 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作:同时由于需求的变化,往往存在着更多系列对象的创建工作.如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种“封装机制”来 ...
-
mysql5.7的安装
1.在官网下载解压缩版 2.解压后配置默认文件 新建个my.ini(可以复制一份my-default.ini,并改名为my.ini).my.ini会替换掉下面的my-default.ini文件. 按需 ...
-
sql截取数据库数字字段内容
round(columnName, precision) 四舍五入 trunc(columnName, precision) 强制截断
-
CC++刚開始学习的人编程教程(9) Windows8.1安装VS2013并捆绑QT与编程助手
我们在Windows8.1安装VS2013并捆绑QT与编程助手须要下列文件. 2. 在虚拟机中开启Windows8.1 3.然后选择VS2013的安装镜像. 4.将镜像拷贝到虚拟机. 5.我们装载这个 ...
-
Redis 代理 twemproxy
4台 redis 服务器 172.16.1.37:6379 - 1 172.16.1.36:6379 - 2 172.16.1.35:6379 - 3 172.16.1.34:6379 ...
-
python中的协程及实现
1.协程的概念: 协程是一种用户态的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来的时候,恢复先前保存的寄存器上下文和栈. 因此,协程能保留 ...
-
SLAM+语音机器人DIY系列:(三)感知与大脑——5.机器人大脑嵌入式主板性能对比
摘要 在我的想象中机器人首先应该能*的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能*行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...
-
对BRD、MRD、PRD、FSD四类产品文档的理解
查阅相关文献并总结了在产品生命周期内比较重要的四类文档—BRD.MRD.PRD.FSD各自的含义以及用法. BRD 1.含义:BRD(business requirement document)— 商 ...