JavaScript基本概念【JavaScript学习笔记(三)】

基本概念

一、严格模式(Strict mode)

严格模式开启检测和一些其他措施,使JavaScript变成更整洁的语言。推荐使用严格模式。在严格模式下,某些保留字务必需要添加一些限制。为了开启严格模式,只需在JavaScript文件或script标签第一行添加如下语句:

    'use strict';

也可以在每个函数上选择性开启严格模式,只需将上面的代码放在函数的开头:

    function functionInStrictMode() {
    'use strict';
    }

明显错误

严格模式给我们明确的错误,否则JavaScript总是静默失败:下面的函数 f() 执行一些非法操作,它试图更改所有字符串都有的只读属性——length:

      function f() {
        'abc'.length = 5;
    }

当你调用上面的函数,它静默失败,赋值操作被简单忽略。让我们将 f() 在严格模式下运行:

        function f_strict() {
            'use strict';
            'abc'.length = 5;
    }

现在浏览器报给我们一些错误:

      > f_strict()
    TypeError: Cannot assign to read only property 'length' of abc

二、基本数据类型

undefined、Null、Boolean、Number、String基本数据类型;Object引用数据类型

1.undefined一般不存在显示的赋undefined值的情况,表示了变量未赋值(未赋值的变量直接被赋予undefined,未声明则直接报错).返回对象为undefined

2.Null空对象指针,返回对象为OBject,undefined派生于Null,if(undefined == nul) //true

3.Boolean ture/false 区分大小写

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			
			/*
			 * 将其他的数据类型转换为Boolean
			 * 	- 使用Boolean()函数
			 * 		- 数字 ---> 布尔
			 * 			- 除了0和NaN,其余的都是true
			 * 
			 * 		- 字符串 ---> 布尔
			 * 			- 除了空串,其余的都是true
			 * 
			 * 		- null和undefined都会转换为false
			 * 
			 * 		- 对象也会转换为true
			 */
			
			var a = 123; //true
			a = -123; //true
			a = 0; //false
			a = Infinity; //true  (无穷大)
			a = NaN; //false
			
			//调用Boolean()函数来将a转换为布尔值
			a = Boolean(a);
			
			a = " ";
			
			a = Boolean(a);
			
			a = null; //false
			a = Boolean(a);
			
			a = undefined; //false
			a = Boolean(a);
			
			console.log(typeof a);
			console.log(a);
			
		</script>
	</head>
	<body>
	</body>
</html>

4.Number 其中八进制字面量在严格模式下是无效的,导致抛出异常

	Number.MAX_VALUE
    1.7976931348623157e+308

    Number.MIN_VALUE 大于0的最小值
    5e-324


    Infinity 表示正无穷
    -Infinity 表示负无穷

    如果使用JS进行浮点运算,可能得到一个不精确的结果
 	所以千万不要使用JS进行对精确度要求比较高的运算	
            /*
			 * 将其他的数据类型转换为Number
			 * 	 转换方式一:
			 * 		使用Number()函数
			 * 			- 字符串 --> 数字
			 * 				1.如果是纯数字的字符串,则直接将其转换为数字
			 * 				2.如果字符串中有非数字的内容,则转换为NaN
			 * 				3.如果字符串是一个空串或者是一个全是空格的字符串,则转换为0
			 * 			- 布尔 --> 数字
			 * 				true 转成 1
			 * 				false 转成 0
			 * 
			 * 			- null --> 数字     0
			 * 
			 * 			- undefined --> 数字 NaN
			 * 
			 * 转换方式二:
			 * 		- 这种方式专门用来对付字符串
			 * 		- parseInt() 把一个字符串转换为一个整数
			 * 		- parseFloat() 把一个字符串转换为一个浮点数
			 */

5.String 可以由单引号或双引号表示, + 号连接字符串 , 用String或toString进行强制转换

        将其他的数据类型转换为String
        * 	方式一:
        * 		- 调用被转换数据类型的toString()方法
        * 		- 该方法不会影响到原变量,它会将转换的结果返回
        * 		- 但是注意:null和undefined这两个值没有toString()方法,
        * 			如果调用他们的方法,会报错
        * 
        *  方式二:
        * 		- 调用String()函数,并将被转换的数据作为参数传递给函数
        * 		- 使用String()函数做强制类型转换时,
        * 			对于Number和Boolean实际上就是调用的toString()方法
        * 			但是对于null和undefined,就不会调用toString()方法
        * 				它会将 null 直接转换为 "null"
        * 				将 undefined 直接转换为 "undefined"

6.Object创建对象是后面的()可以省略,但是不推荐。其中Object对象中有以下默认方法:

  • Constructor:保存用于创建当前对象的函数Object()
  • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在,如:o.hasOwnProperty(“name”);
  • isPrototypeOf(object)用于检查传入对象是否是另外一个对象的原型
  • propertyIsEneumerable(propertyName):用于检查传入的对象是否能够使用for-in语句来枚举
  • toLacationString():返回对象的字符串表示,该字符串与执行环节的地区对象
  • toString()返回对象的字符串表示
  • valueOf()返回对象的字符串、数值或布尔值表示

三、操作符

一元运算符、位操作符、布尔操作符、乘性操作符、加性操作符、关系操作符、相等操作符、条件操作符、赋值操作符、逗号操作符

位运算符

非:
var num1 =25
//二进制00000000000000000000000000011001
var num2  = ~num1:
//二迸制11111111111111111111111111100110
a lert(num2) //-26

与:
var result =25 & 3
alert(result); //1
//同1非0

或:
var result =25 | 13
alert(result); //27
//有一为一


异或(XOR):
同为1,异为0

左移<< 2的几次方倍数 //原理是向左移动n位,后面补0

右移>> 除以2的几次方倍数

关系运算符:

			
			console.log(1 > true); //false
			console.log(1 >= true); //true
			console.log(1 > "0"); //true
			console.log(10 > null); //true
			// 任何值和NaN做任何比较都是false
			console.log(10 <= "hello"); //false
			console.log(true > false); //true
			

			console.log("1" < "5"); //true


			console.log("11" < "5"); //true   ????

			
			//比较两个字符串时,比较的是字符串的字符编码
			console.log("a" < "b");//true
			//比较字符编码时是一位一位进行比较
			//如果两位一样,则比较下一位,所以借用它来对英文进行排序
			console.log("abc" < "bcd");//true
			//比较中文时没有意义
			console.log("戒" > "我"); //true
			
			//如果比较的两个字符串型的数字,可能会得到不可预期的结果
			//注意:在比较两个字符串型的数字时,一定一定一定要转型
			console.log("11123123123123123123" < +"5"); //true
			

相等运算符:


<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			
			/*
			 * 相等运算符用来比较两个值是否相等,
			 * 	如果相等会返回true,否则返回false
			 * 
			 * 使用 == 来做相等运算
			 * 	- 当使用==来比较两个值时,如果值的类型不同,
			 * 		则会自动进行类型转换,将其转换为相同的类型
			 * 		然后在比较
			 * 不相等
			 * 	 不相等用来判断两个值是否不相等,如果不相等返回true,否则返回false
			 * 	- 使用 != 来做不相等运算
			 * 	- 不相等也会对变量进行自动的类型转换,如果转换后相等它也会返回false
			 * 
			 * 		
			 *  ===
			 * 		全等
			 * 		- 用来判断两个值是否全等,它和相等类似,不同的是它不会做自动的类型转换
			 * 			如果两个值的类型不同,直接返回false
			 * 	!==
			 * 		不全等
			 * 		- 用来判断两个值是否不全等,和不等类似,不同的是它不会做自动的类型转换
			 * 			如果两个值的类型不同,直接返回true
			 */
			
			//console.log(1 == 1); //true
			
			var a = 10;
			var a = null;

			//console.log(a == 4); //false
			
			//console.log("1" == 1); //true
			
			//console.log(true == "1"); //true
			
			//console.log(null == 0); //false
			
			/*
			 * undefined 衍生自 null
			 * 	所以这两个值做相等判断时,会返回true
			 */
			//console.log(undefined == null);
			
			/*
			 * NaN不和任何值相等,包括他本身
			 */
			//console.log(NaN == NaN); //false
			
			var b = NaN;
			
			//判断b的值是否是NaN
			//console.log(b == NaN);
			/*
			 * 可以通过isNaN()函数来判断一个值是否是NaN
			 * 	如果该值是NaN则返回true,否则返回false
			 */
			// console.log(isNaN(b));
			
			//console.log(10 != 5); //true
			//console.log(10 != 10); //false
			//console.log("abcd" != "abcd"); //false
			//console.log("1" != 1);//false
			
			//console.log("123" === 123);//false
			//console.log(null === undefined);//false
			console.log(1 !== "1"); //true
		</script>
	</head>
	<body>
	</body>
</html>

四、函数

理解函数

普通模式下:

function doAdd(num1, num2 ){I
	arguments[1]=10;
	alert(arguments [0]+ num2);
}

每次传入参数时,第二的参数都会被修改为10。

严格模式对如何使用arguments对象做出了一些限制。首先,像前面例子中那样的赋值会变得无效。也就是说,即使把 arguments[1]设置为10,num2的值仍然还是 undefined。其次,重写arguments的值会导致语法错误(代码将不会执行)

没有重载

ECMAScript函数不能像传统意义上那样实现重载。而在其他语言(如Java)中,可以为一个函数,编写两个定义,只要这两个定义的签名(接受的参数的类型和数量)不同即可。

如果在 ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数。

function addSomeNumber(num){
return num +100;}
function addsomeNumber(num){
return num +200;}
var result addSomeNumber(100);//300

如前所述,通过检查传入函数中参数的类型和数量并作出不同的反应,可以模仿方法的重载。

模仿重载实现:

function addMethod(object, name, fn)
{
    var old = object[name];
    object[name] = function()
    {
        if (fn.length == arguments.length)
            return fn.apply(this, arguments);
        else if (typeof old == 'function')
            return old.apply(this, arguments);
    };
}


// 不传参数时,返回所有name
function find0()
{  
    return this.names;
}


// 传一个参数时,返回firstName匹配的name
function find1(firstName)
{  
    var result = [];  
    for (var i = 0; i < this.names.length; i++)
    {    
        if (this.names[i].indexOf(firstName) === 0)
        {      
            result.push(this.names[i]);    
        }  
    }  
    return result;
}


// 传两个参数时,返回firstName和lastName都匹配的name
function find2(firstName, lastName)
{ 
    var result = [];  
    for (var i = 0; i < this.names.length; i++)
    {    
        if (this.names[i] === (firstName + " " + lastName))
        {      
            result.push(this.names[i]);    
        }  
    }  
    return result;
}


function Users()
{
    addMethod(Users.prototype, "find", find0);
    addMethod(Users.prototype, "find", find1);
    addMethod(Users.prototype, "find", find2);
}


var users = new Users();
users.names = ["John Resig", "John Russell", "Dean Tom"];


console.log(users.find()); // 输出[ 'John Resig', 'John Russell', 'Dean Tom' ]
console.log(users.find("John")); // 输出[ 'John Resig', 'John Russell' ]
console.log(users.find("John", "Resig")); // 输出[ 'John Resig' ]
console.log(users.find("John", "E", "Resig")); // 输出undefined

从效果上来说,users对象的find方法允许3种不同的输入: 0个参数时,返回所有人名;1个参数时,根据firstName查找人名并返回;2个参数时,根据完整的名称查找人名并返回。

难点在于,users.find事实上只能绑定一个函数,那它为何可以处理3种不同的输入呢?它不可能同时绑定3个函数find0,find1与find2啊!这里的关键在于old属性。

由addMethod函数的调用顺序可知,users.find最终绑定的是find2函数。然而,在绑定find2时,old为find1;同理,绑定find1时,old为find0。3个函数find0,find1与find2就这样通过闭包链接起来了。

根据addMethod的逻辑,当fn.length与arguments.length不匹配时,就会去调用old,直到匹配为止。

五、注意点

1.如果使用类似于C语言的最好始终添加代码块

 if(test)
    alert(test);  //有效但是容易出错
if(test){
    alert(test); //推荐使用
}

2.for-in循环

for (var propName in window)(
document.write(propName);}

ECMAScript对象的属性没有顺序。因此,通过for-in循环输出的属性名的顺序是不可预测的。不过所有属性都会被返回一次,但返回的先后次序可能会因浏览器而异。

但是,如果表示要迭代的对象的变量值为mu11或 undefined,for-in语句会抛出错误。

ECMAScript5更正了这一行为;对这种情况不再抛出错误,而只是不执行循环体。为了保证最大限度的兼容性,建议在使用for-in循环之前,先检测确认该对象的值不是nu11或undefined

3.由于不存在函数签名的特性, ECMAScript函数不能重载。但是可以通过模仿重载的特性,实现重载的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值