那些必须要知道的Javascript

原文:那些必须要知道的Javascript

      JavaScript是前端必备,而这其中的精髓也太多太多,最近在温习的时候发现有些东西比较容易忽略,这里记录一下,一方面是希望自己在平时应用的时候能够得心应手,另一方面也希望能给别人带来一点点的收获。

      一、JavaScript的==和===,即相等运算符和等同运算符。

      相等运算符,如果操作数有相同的类型,则判断其等同性,如果两个操作数的值相等,则返回true(相等),否则返回false(不相等);

      如果类型不同,则按照这样的情况来判断:

      null和undefined相等;数字与字符串字符比较,字符串转化为数字再比较;其中一个为true转化为1再做比较;如果一个值是对象,另一个是数字或者字符串,则将对象转化为原始值(通过toString()或者valueOf()方法),其他返回false。

      等同运算符,如果操作数类型不一样,直接返回false,类型相同,如下判断:

      1、都是数字,若值相同,则两者等同但是NAN除外,因为NAN与本身也不等,否则不相同;

      2、都是字符串的情况:值不等则不等同,否则等同;

      3、都是布尔值,均为true/false则等同否则不等同;

      4、如果两个操作数引用同一对象(数组或函数)则等同,否则不等;

      5、均为null/undefined则等同。

       二、函数作用域

       作用域在所有语言中都有体现,只是在Javascript脚本里有其特殊性-->Javascript中的作用域为函数体内有效,而无块儿作用域。在Java或者C#中,我们可以写出下面的循环:

public void method(string obj1,string obj2){
for(int i=0;i<obj1.length;i++){
//do  something
}
//此时的i为未定义
for(int i=0;i<obj2.length;i++){
//do another thing
}
}

View Code

而在Javascript中不同:

function func(){
for(var i = 0; i < array.length; i++){
//do something here.
}
//此时i仍然有值,及I == array.length
print(i);//i == array.length;
}

View Code

      Javascript的函数是在局部作用域内运行的,在局部作用域内运行的函数体可以访问其外层的(可能是全局作用域)的变量和函数。JavaScript的作用域为词法作用域,所谓词法作用域是说,其作用域为在定义时(词法分析时)就确定下来的,而并非在执行时确定,如下例:

var str = "global";
function scopeTest(){
print(str);
var str = "local";
print(str);
}
scopeTest();

View Code

      您觉得运行结果是什么呢?global local或者local  local 再或者其他?而正确的结果却是 undefined   local,没错,undefined  local!

      因为在函数scopeTest的定义中,预先访问了未声明的变量str,然后才对str变量进行初始化,所以第一个print(str)会返回undifined错误。那为什么函数这个时候不去访问外部的str变量呢?这是因为,在词法分析结束后,构造作用域链的时候,会将函数内定义的var变量放入该链,因此str在整个函数scopeTest内都是可见的(从函数体的第一行到最后一行),由于str变量本身是未定义的,程序顺序执行,到第一行就会返回未定义,第二行为str赋值,所以第三行的print(str)将返回”local”。

      三、数组操作

      常用的对数组的操作:

      contact() 连接两个或更过的数组,并返回结果

      join() 把数组所有元素放入一个字符串,元素通过指定的分隔符进行分隔

      pop() 删除并返回最后一个元素与push()对应,向数组末尾添加一个或更多元素,并返回新长度;类似于压栈和弹栈

      reverse() 颠倒元素的顺序

      shift() 删除并返回第一个元素

      slice() 从已有数组返回制定数组

      sort() 对数组元素排序,默认按字母排序,也可按数字大小排:array.sort(function(a,b){return a-b});

      splice()删除元素,并添加新元素

      unshift()向数组开头添加一个或更多元素,并返回新的长度

      valueOf() 返回数组对象的原始值

      四、JavaScript闭包特性

      我们来看一个例子,如果不了解JavaScript的特性,很难找到原因:

var outter = [];
function clouseTest () {
var array = ["one", "two", "three", "four"];
for(var i = 0; i < array.length;i++){
var x = {};
x.no = i;
x.text = array[i];
x.invoke = function(){
print(i);
}
outter.push(x);
}
}
//调用这个函数
clouseTest();
print(outter[0].invoke());
print(outter[1].invoke());
print(outter[2].invoke());
print(outter[3].invoke());

View Code

      运行的结果如何呢?0 1 2 3?这是很多人期望的答案,可是事实真的是这样吗?马上运行一下吧,是不是惊呆了?结果居然是4 4 4 4 !

      其实,在每次迭代的时候,这样的语句x.invoke = function(){print(i);}并没有被执行,只是构建了一个函数体为”print(i);”的函数对象,如此而已。而当i=4时,迭代停止,外部函数返回,当再去调用outter[0].invoke()时,i的值依旧为4,因此outter数组中的每一个元素的invoke都返回i的值:4。如何解决呢,我们可以声明一个匿名函数,然后马上执行它。

function clouseTest2(){
var array = ["one", "two", "three", "four"];
for(var i = 0; i < array.length;i++){
var x = {};
x.no = i;
x.text = array[i];
x.invoke = function(no){
return function(){
print(no);
}
}(i);
outter.push(x);
}
}

View Code

      这个例子中,我们为x.invoke赋值的时候,先运行一个可以返回一个函数的函数,然后立即执行之,这样,x.invoke的每一次迭代器时相当与执行这样的语句:

//x == 0
x.invoke = function(){print(0);}
//x == 1
x.invoke = function(){print(1);}
//x == 2
x.invoke = function(){print(2);}
//x == 3
x.invoke = function(){print(3);}

View Code

      这样就可以得到正确的结果了。

      可以根据Object.prototype.toString.Call(source)来判断给定对象的类型。另外还有两个地方需要注意:

      1、如果变量作用域为函数内部则,则外部无法访问,如:

var person=function(){
var name="default";
return {
getName:function(){return name;},
setName:function(no){name=no}
}
}();
print(person.name)//undefined

View Code

      2、引用

      引用也是一个比较有意思的主题,JavaScript中的引用始终指向最终的对象,而并非引用本身,我们来看一个例子:    

var obj = {};//空对象
var ref = obj;//引用
obj.name = "objectA";
print(ref.name);//ref跟着添加了name属性
obj = ["one", "two", "three"];//obj指向了另一个对象(数组对象)
print(ref.name);//ref还指向原来的对象
print(obj.length);//3
print(ref.length);//undefined

View Code

      运行结果:

      objectA
      objectA
       3
      undefined

      obj只是对一个匿名对象的引用,所以,ref并非指向它,当obj指向另一个数组对象时可以看到,引用ref并未改变,而始终指向那个后来添加了name属性的"空"对象”{}”。理解这个之后,下面这个例子就不难了:

var obj = {};//新建一个对象,并被obj引用
var ref1 = obj;//ref1引用obj,事实上是引用obj引用的空对象
var ref2 = obj;
obj.func = "function";
print(ref1.func);
print(ref2.func);

View Code

      声明一个对象,然后用两个引用来引用这个对象,然后修改原始的对象,注意这两步的顺序,运行之:

     function
     function

     根据运行结果我们可以看出,在定义了引用之后,修改原始的那个对象会影响到其引用上,这一点也应该注意。

     以上是最近发现的一些易错的地方,也希望您能将您遇到的易错问题分享出来,一起学习,共同进步!

 

      

时间: 2024-10-23 22:10:45

那些必须要知道的Javascript的相关文章

你未必知道的JavaScript和CSS交互的5种方法

 网页中都有.js文件和.css文件,但这并不意味着CSS和js是独立不能交互的,下面与大家分享js与css交互的5种方法 随着浏览器不断的升级改进,CSS和JavaScript之间的界限越来越模糊.本来它们是负责着完全不同的功能,但最终,它们都属于网页前端技术,它们需要相互密切的合作.我们的网页中都有.js文件和.css文件,但这并不意味着CSS和js是独立不能交互的.下面要讲的这五种JavaScript和CSS共同合作的方法你也许未必知道!    用JavaScript获取伪元素(pseud

你未必知道的JavaScript和CSS交互的5种方法_javascript技巧

随着浏览器不断的升级改进,CSS和JavaScript之间的界限越来越模糊.本来它们是负责着完全不同的功能,但最终,它们都属于网页前端技术,它们需要相互密切的合作.我们的网页中都有.js文件和.css文件,但这并不意味着CSS和js是独立不能交互的.下面要讲的这五种JavaScript和CSS共同合作的方法你也许未必知道! 用JavaScript获取伪元素(pseudo-element)属性 大家都知道如何通过一个元素的style属性获取它的CSS样式值,但能获取伪元素(pseudo-eleme

一些老手都不一定知道的JavaScript技巧_javascript技巧

一些不太常用但强大的JavaScript小技巧,新手和老手js开发人员都不一定知道. 1.截断数组与数组长度 复制代码 代码如下: var arr1 = arr2 = [1, 2, 3]; //改变 arr1arr1 = []; // arr2则任然是 [1,2,3] 你会发现arr1用[]方法来清空不会影响arr2的值,假如要想让arr1改变后arr2跟着一起改变 ,则可以这样 复制代码 代码如下:  var arr1 = arr2 = [1, 2, 3];arr1.length=0; //注

5种你未必知道的JavaScript和CSS交互的方法

随着浏览器不断的升级改进,CSS和JavaScript之间 的界限越来越模糊.本来它们是负责着完全不同的功能,但最终,它们都属于网页前端技术,它们需要相互密切的合作.我们的网页中都有.js文件和.css文 件,但这并不意味着CSS和js是独立不能交互的.下面要讲的这五种JavaScript和CSS共同合作的方法你也许未必知道! 用JavaScript获取伪元素(pseudo-element)属性 大家都知道如何通过一个元素的style属性获取它的CSS样式值,但能获取伪元素(pseudo-ele

站长必须要知道的javascript广告代码[原创]_广告代码

参考了sina的代码,想出来的一个代码,请大家使用,不要传播,转载请注明:来自<!-- //时间计算 var showit=false; var today=new Date(); var urlpath; function testdate() { urlpath='http://www.scripthome.net/bbs';showit=true if(today.getHours()>='10' && today.getHours()<'12') {     ur

我希望自己尽早知道的 7 个 JavaScript 怪癖

如果对你来说JavaScript还是一门全新的语言,或者你是在最近的开发中才刚刚对它有所了解,那么你可能会有些许挫败 感.任何编程语言都有它自己的怪癖(quirks)--然而,当你从那些强类型的服务器端语言转向JavaScript的时候 ,你会感到非常困惑.我就是这样!当我在几年前做全职JavaScript开发的时候,我多么希望关于这门语言的许多事情我能尽早地知道.我希望通过本文中分享的一些怪癖能让你免于遭受我所经历过的那些头疼的日子.本文并非一个详尽的列表,只是一些取样,目的是抛砖引玉,并且让

网站开发人员应该知道的61件事

有人在Stack Overflow上发问,动手开发网站之前,需要知道哪些事情? 不出意料地,他得到了一大堆回答. 通常情况下,你需要把所有人的发言从头到尾读一遍.但是,Stack Overflow有一个很贴心的设计,它允许在问题下方开设一个wiki区,让所有人共同编辑一个最佳答案.于是,就有了下面这篇文章,一共总结出六个方面共计61条"网站开发须知". 我发现,这种概述性的问题,最适合这种集合群智.头脑风暴式的回答方式了.这也是我第一次觉得,Stack Overflow做到了Wikip

你应该知道的10件关于Java 6的事情

<What's New in Java SE 6 Beta 2>一文中描述了你应该知道的10件关于Java 6的事情,下面总结如下 1.Web Services. 优先支持编写 XML web service 客户端程序.你可以用过简单的annotaion将你的API发布成.NET交互的web services. Mustang 添加了新的解析和 XML 在 Java object-mapping APIs中, 之前只在Java EE平台实现或者Java Web Services Pack中提

关于Node.js:所有PHP开发人员应该知道的5点

我最近开始和Node.js打交道.以前做PHP开发,特别是Drupal,我发现向Node.js转移很容易,而且过程很愉快!但是我也需要学会从 一些不同的角度思考.下面我列出了5项我认为PHP工程师应该知道的Node.js特点. 1. Node.js是构建于Chrome的JavaScript引擎的 Google的浏览器Chrome,有一个非常快速的JavaScript引擎,叫做V8.这个JS引擎可以被独立出来.Node.js就是建立在V8之上的.这 也是为什么Node.js会运行的如此之快.对于开