读javascript权威指南

javascript 权威指南:
1)XHTML区分大小写;
2)javascript 代码两行之间可以不加入分号,会默认插入;
3)isNaN():是否不是数字,NaN和任何值都不相等
4)数字转字符串T:
var num=17; console.log(typeof (num+"")=="string");//true
var num=17;console.log("0x"+nun.toString(16));//0x11
5)字符串转换为数字T:
var num="20"*"2";console.log(num);//40
var num="20"-0;console.log(typeof num);//number
var num="11aa"-0;console.log(num);//NaN
console.log(typeof NaN);//number
6)var num={"name":"jj","sex":"male"};console.log(num.toString());//[object Object]
7)
数字环境null=0:var num=null+2;console.log(num);//2
布尔环境null=false:var num=null&&true;console.log(num);

var s1="hello world";
var s2=s1.substring(0,2);
此句的伪代码为:
var s1=new String("hello world");//创建String 类型的一个实例
var s2=s1.substring(0,2);//通过实例调用指定方法
s1=null;//销毁这个实例

从上我们可以总结下 引用类型和基本包装类型的区别:
a)使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前一直保持在内存中,
而自动创建的包装类对象,只存在于一行代码的执行瞬间,然后立即被销毁。因此,我们不能在运行时为基本
包装类型添加属性和方法。
console.log(typeof (new Date()));//object
var s1=new String("hello world");
var s2="hello world";
console.log(typeof s2);//string
if(s1){
 console.log("基本包装类型对象在布尔环境中都会转换为布尔值true");
}
再来看看Boolean类型
var falseObj=new Boolean(false);
var res=falseObj&&true;

console.log(res);//true
console.log(falseObj instanceof Boolean);//true
console.log(falseObj instanceof Object);//true

不管何时,非空对象用在布尔环境中的时候,都转换为true,对于所有对象(包括数组、函数、包装类型对象)都是成立的。
而
var falseObj=false;
var res=falseObj&&true;
console.log(res);//false
8)类型间的转换
console.log([].toString());//空字符串
console.log(["1"].toString());//string 1
console.log(["1abc","ccc"].toString());//string 1abc,ccc

console.log(new Date()+222);//得到字符串Tue Jun 04 2013 23:31:08 GMT+0800222
console.log();

 

9)传值和传址
复制:
1)传值: 实际复制的是值,存在两个不同的、独立的拷贝;
2)传址:复制的只是对数值的引用,如果通过这个新的引用修改了值,这个改变对最初的引用来说也可见
传递:
1)传值:传递给函数的值是一个独立的拷贝,对他的改变在函数外部没有任何影响
2)传址:传递给函数的是一个对数值的引用,如果函数通过传递给它的引用修改了值,那么这个值在外部也是可见的。
比较:
1)传值:比较的是两个独立的值;
2)传址:比较是两个引用,以判断他们引用的是否是同一个值;
javascript中规则:
基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置;(Number/Boolean/String/Null/Undefined),占用的内存空间大小固定。
引用类型值指的是那些保持在堆内存中的对象,即变量中保存的实际上是一个指针,这个指针指向内存中的另一个位置,
这个位置保存对象;(对象、数组和函数),内存地址(指针)保存在栈内存中,查询引用的类型的变量时,首先是从栈内存中读取内存地址,然后
找到保存在堆中的值。
ECMAScript中所有函数的参数都是按值传递

看看实例:
function demo01(){
 var a="hello";
 var b=a;
 a="world";
 //此处的a确切来讲,a="world";并不是修改a,而是创建了一个新字符串(相应地,在内存中分配一块新空间),
 //然后让a引用该字符串——更像是替换变量的值;原来的字符串呢?因为没有变量引用它,也就成为垃圾了(当然,垃圾所占用的内存会被回收)。
 console.log(b);
 console.log(a);
}
demo01();

function demo02(obj){
 obj.name="hello world";
}
obj01={};
demo02(obj01);
console.log(obj01.name);//hello world

function demo03(obj){
 obj.name="hello world";
 obj=new Object();//此处重写obj时,这个变量的引用就是一个局部对象,局部对象在函数执行完毕后会立即销毁
 obj.name="Welcome beijing";
}
obj01={};
demo02(obj01);
console.log(obj01.name);//hello world

由demo03可以看出,javascript中引用类型的函数参数传递也是按值传递的。


10)变量的作用域:
规则:
顶层作用域(window)》Object类属性的作用域》Object原型属性的作用域》var 变量所在的作用域》闭包作用域》函数作用域
javascript 中没有块级作用域
function demo04(){
 var i=0;
 if(typeof i =="number"){
  var j=0;
  for(var k=0;k<l0;k++){
   console.log(k);
  }
 }
}
在此函数中i、j、k的作用域是相同的;它们在整个demo04函数体内都是有定义的

11)javascript 运算符:
a)i++,++i:
var i=1;
var j=++i;
//i=i+1;j=i;
console.log(i);//2
console.log(j);//2
var i=1;
var j=i++;
//j=i;i=i+1;
console.log(i);//2
console.log(j);//1
b)in:
in左边的字符串是右边对象或者数组的一个属性名,返回true,常用在对象遍历中
var arr=["aa","bbb","cccc"];
var obj={"x":"aa","y":"bb"};
console.log("x" in obj);//true
console.log("x" in Object);//false
console.log("0" in arr);//true
c)instanceof:
console.log(obj instanceof Object);//true
console.log(arr instanceof Array);//true

d)
~运算符:按位取反的操作
^:按位异或
var selector="#layout";
var pattern = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
var match =  pattern.exec( selector );
if(match&&~match[0].indexOf("#")){
 var id=document.getElementById(match[2]);
 console.log(match);//["#layout", undefined, "layout"]
}
原码:符号位+数值的二级制码
补码:正数的补码与原码相同,负数的补码等于其原码的符号位不变,数值部分的各位取反,然后整个数加1。
console.log(~0);//-1
console.log(~-1);//0
console.log(~2);//-3
对一个值使用~运算符,相当于改变它的符号后的值减1

var pattern=/^(zo)*$/g;
var match=pattern.exec("zozo");
console.log(match);//["zozo", "zo"]
exec()函数返回包含第一个匹配项信息的数组,如果么有匹配项返回null
数组第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串

e)void运算符:
其可以出现在任何操作数之前,这个运算符的用途比较特殊,它总是舍弃运算数的值,然后返回undefined;在实际使用中,
我们通常使用void地方在<a href="www.baidu.com" οnclick="aa()">fafdasdfasfdasfd</a>标签中,请看demo01:
i)demo01:
<!doctype html>
<html>
 <body>
 <a href="http://www.baidu.com" οnclick="aa()">fafdasdfasfdasfd</a>
 <script type="text/javascript">
  function aa(){
   alert("jsdemo");
  }
 </script>
 </body>
</html>
当点击a链接时首先触发aa()方法,弹出"jsdemo",然后跳转到baiduc.com
ii)demo02
<!doctype html>
<html>
 <body>
 <a href="javascript:void 1" οnclick="aa()">fafdasdfasfdasfd</a>
 <script type="text/javascript">
  function aa(){
   alert("jsdemo");
  }
 </script>
 </body>
</html>
demo02中只会弹出jsdemo;因为console.log(void 1);//undefined
iii)demo03:
<!doctype html>
<html>
 <body>
 <a href="http://www.baidu.com" οnclick="aa(event)">fafdasdfasfdasfd</a>
 <script type="text/javascript">
  function aa(e){
   var e=e||window.event;
   alert("jsdemo");
    if (e && e.preventDefault) {//如果是FF下执行这个
    e.preventDefault();
   }else{ 
    e.returnValue = false;//如果是IE下执行这个
   }
  }
 </script>
 </body>
</html>
demo03中只会弹出jsdemo;阻止了a标签的默认事件;

f)[]运算符:
可用来存在数组元素或者对象的属性,当遍历一个对象时是很常用的
var obj={
 "x":1,
 "y":"demo01",
 "z":{"w":1,"u":"u"},
 "w":[1,2,"cc"]
}
console.log(obj["w"]);//[1,2,"cc"]
for(f in obj){
 console.log(f+"----"+obj[f]);
}
result:
x----1
y----demo01
z----[object Object]
w----1,2,cc//此时数组和字符串拼串,自动转换为字符串

12)表达式语句:
try/catch/finally:
try块中至少有一个catch块和finally块
当try和finally一起使用时,无论try块中有break、continue、return 语句,finally中的语句都会执行
如下demo01:
for (var i=0; i<3; i++){
 try{
  if(typeof i ==="number"){
   break;
  }
 }finally{
  i++;
  console.log(i);//输出:1
 }
}
for (var i=0; i<3; i++){
 try{
  if(typeof i ==="number"){
   continue;
  }
 }catch(e){
  console.log("error");
 }finally{
  i++;
  console.log(i);//输出:1,3
 }
}
with语句:
with(obj){
 //执行代码
}
常用于扩展作用域链,能够有效地将obj添加到作用域链的头部,然后执行statement,再把作用域链回复到以前状态,
但是因使用with语句的代码很难优化,而且性能也比较低,所以一般不赞成使用

13)通用的Object属性和方法:
a)constructor
var d=new Date();
console.log(d.constructor==Date);//true
确定某个对象的类型:
var o=new Date();
if(typeof o==="object"&&o.constructor===Date){
	console.log("aa");//aa
}
if(typeof o==="object"&&o instanceof Date){
	console.log("aa");//aa
}
b)toString():
var str="aaa";
var obj={"name":"bbb","sex":"ccc"};
console.log(str+obj);//aaa[object Object]
alert(obj);//[object Object]
判断一个变量是否为数组:
var arr=["aa",1,"bb"];
if(Object.prototype.toString.call(arr)==="[object Array]"){
	console.log(arr.join("*"));//aa*1*bb
}

c)hasOwnProperty(propertyName):
用于检查给定的属性存在于当前对象实例中(而不在实例的原型中)
function Person(name){
	this.name=name
}
Person.prototype.setName=function(name){
	this.name=name;
}
var person=new Person("aaaa");
console.log(person.hasOwnProperty("name"));//true
console.log(person.hasOwnProperty("setName"));//false

14)数组的方法:
reverse()、sort()、join()
concat():
var arr=["aaaa","bb",2];
console.log(arr.concat(2,"cc"));//["aaaa", "bb", 2, 2, "cc"]
console.log(arr.concat([2,"cc"]));//["aaaa", "bb", 2, 2, "cc"]
console.log(arr.concat([2],["cc"]));//["aaaa", "bb", 2, 2, "cc"]
console.log(arr.concat(2,[2],["cc",[6,7,8,9]]));//["aaaa", "bb", 2, 2, 2, "cc", [6, 7, 8, 9]]

slice():
var arr=[1,2,3,4,5,6,7,8,9];
console.log(arr.length);//9
console.log(arr.slice(0,3));//[1, 2, 3]
console.log(arr.slice(4));//[5, 6, 7, 8, 9]
console.log(arr.slice(-3,-1));//[7, 8]
<==>console.log(arr.slice(6,8));
console.log(arr.slice(-1,-3));//[]
<==>console.log(arr.slice(8,6));
console.log(arr.slice(1,-3));//[2, 3, 4, 5, 6]
<==>console.log(arr.slice(1,6));

splice():
插入或删除数组的通用方法:始终返回一个数组,数组中包含从原始数组中删除的项(否则返回空数组)
var arr=[1,2,3,4,5,6,7,8,9];
console.log(arr.splice(0,3));删除操作//[1,2,3]
console.log(arr);//[4, 5, 6, 7, 8, 9]
console.log(arr.splice(2,0,"cc","bb"));//插入操作,返回空数组[]
console.log(arr);//[4, 5, "cc", "bb", 6, 7, 8, 9]
console.log(arr.splice(2,1,"dd","eee","fff"));//替换["cc"]
console.log(arr);//[4, 5, "dd", "eee", "fff", "bb", 6, 7, 8, 9]

push():返回数组的新长度
pop():返回删除的元素
栈方法:先进后出(数组的尾部操作)

unshift():返回数组的新长度
shift():返回删除的元素
队列方法:先进先出(数组的头部操作);


15)函数:
参数arguments对象:
var fn=function(x,y){
	
	console.log(x+"----"+y);
}
fn(1,2,"aa");//1----2
fn(1,2);//1----2
fn(1);//1----undefined

var fn=function(x,y){
	var y="aaa"
	console.log(x+"----"+y);
}
fn(1,2);//1----aaa

var fn=function(x,y){
	arguments[0]="aaa"
	console.log(x+"----"+y);
}
fn(1,2);//aaa----2

注意下面demo:
var fn=function(x,y){
	var x="bb";
	arguments[0]="aaa"
	console.log(x+"----"+y);
}
fn(1,2);//aaa----2


方法:
apply(),call():

1)var fn=function(x,y){
	console.log(x+"**"+y);
}
var obj={
	fun:fn
};
console.log(obj.fun(2,3));//2**3

2)fn.call(obj,1,2);//1**2
=>window.fn.call(obj,1,2);
把1,2参数传递给fn,并把fn作为obj对象的方法调用
obj.fun=f;
obj.fun(1,2);
delete obj.fun;

3)fn.apply(obj,[1,2]);
a)找出一个数字数组中最大数字
var arr=[1,3,6,2,5,9,0];
var biggest=Math.max.apply(null,arr);
var str=Array.prototype.slice.apply(arr,[1,3]);
console.log(biggest);//9
console.log(str);//[3, 6]

16)对象工具函数:
/*
  获取属性名集合
  @param {object}
  @retrun {array}
*/
function getPropertyNames(o){
	var arr=[];
	for(name in o){
		arr.push(name);
	}
	return arr;
}
/*
  copy对象集合
  @param {object}//源对象
  @param {object}//目的对象
  @return {object}//返回对象
*/
function copyProperties(obj,newobj){
	var newobj=newobj||{};
	for(name in obj){
		newobj[name]=obj[name];
	}
	return newobj;
}
/*
  模拟jquery中合成对象
  @param {object}//源对象
  @param {object}//目的对象
  @return {object}//返回对象
*/
function extend(){
	var target=arguments[0]||{},
		i=1,
		len=arguments.length,
		options,
		name,
		src,
		dest,
		deep=false;
	if(typeof target ==="boolean"){
		deep=target;
		i=2;
		target=arguments[1]||{};
	}
	if(typeof target!=="object"&&typeof target!=="function"){
		target={};
	}
	for(;i<len; i++){
		console.log(i);
		if((options=arguments[i])!=null){
			for(name in options){
				var src=target[name];
				var dest=options[name];
				if(src==dest){
					continue;
				}
				//深度拷贝
				if(deep&&dest&&(typeof dest==="object"||Object.prototype.toString.call(dest)==='[object Array]')){
                    var clone = src && (typeof src==="object"|| Object.prototype.toString.call(src)==='[object Array]') ? src : typeof dest==="object" ? {} : [];  
					target[name]=extend(deep,clone,dest);
				}
				//浅度拷贝
				else if(dest !== undefined){
					target[name]=dest;
				}
			}
		}
	}
	return target;
}
//看一个demo:
var s={
	"name":{
		"11":"11"
	},
	"sex":"male",
	"age":30
}
var d={
	"name":{
		"11":"22",
		"22":"44"
	},
	"student":false,
}
var c={
	"name":{
		"11":"33",
		"33":"555"
	},
	"my":"me"
}
console.log(extend(true,s,d,c));



 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值