JavaScript知识(一直更新)


1、匿名函数从语法上叫函数直接量,JavaScript语法需要包围匿名函数的括号,事实上自调用匿名函数有两种写法:
(function() {
console.info( this );
console.info( arguments );
}( window ) );
--------------------------------------------------------------------------
(function() {
console.info( this );
console.info( arguments );
})( window );   

经测试:不是匿名函数也是可以的。


2、函数名前有一元操作符

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. +function(){}();  

这里的加号,也可以替换成!,~,-等其他一元操作符,其效果相当于:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. (function() { console.log("Foo!"); })();  
  2. // or  
  3. (function() { console.log("Foo!"); }());  

如果没有这个加号的话,解析器会认为function是一个函数声明的开始,而后面()将会导致语法错误。在function前面加上+号时,就变成了一个函数表达式,而函数表达式后面又添加了一个()就变成了一个立即执行的函数了。


3、JavaScript 的字符串是不可变的(immutable),String 类定义的方法都不能改变字符串的内容。像 String.toUpperCase() 这样的方法,返回的是全新的字符串,而不是修改原始字符串。


4、如下代码

<script type="text/javascript">
   a = function ddd(  ) {alert(1)}
   alert(a.name)
   a()
   a = function fff(  ) {alert(2)}
   alert(a.name)
   a() ddd()
</script>   

结果为:ddd,1,fff, 2,错误(ddd未定义)

另说明 js语句可以不用分号;结尾


5、如下代码

if(0) {
	alert(1);
}
if(0.0) {
	alert(2);
}
if(NaN) {
	alert(3);
}
if(false) {
	alert(4);
}
if(null) {
	alert(5);
}
if(undefined) {
	alert(6);
}
if("") {
	alert(7);
}
if([]) {
	alert(8);
}
if({}) {
	alert(9);
}
if(function(){}) {
	alert(10);
}

输出 8,9,10  和php不同,php中好像空对象,空数组也是false,这里他们是复合数据类型,代表了地址。


js基本数据类型: number, string, boolean

复合数据类型:对象,数组,函数

其他:null, undefined


6、如下代码

	function test(a) {
		alert(a == null);            //true
		alert(a == undefined);       //true
		alert(a === null);           //false
		alert(undefined == null);    //true
		alert(a === undefined);      //true
		alert(typeof a);             //undefined
		alert(typeof null == "object");   //true
		alert(typeof [] == "object");     //true
		var s = "fdf"; 
		alert(typeof s == "string");     //true
		var s = new String("fdf");     //不会报重定义错误
		alert(typeof s == "object");     //true
	}
	test();

7、如下代码

if(NaN === NaN) {
	alert(1);
}
if(Infinity === Infinity) {
	alert(2);
}
if(null === null) {
	alert(3);
}
if(undefined === undefined) {
	alert(4);
}
if("" === "") {
	alert(5);
}

只有NaN !== 自己


8、深度复制

	function cp(object) {
		var obj = {};
		for(var i in object) {
			if(typeof object[i] === "object") {
				obj[i] = cp(object[i]);
			} else {
				obj[i] = object[i];
			}
		}
		return obj;
	}
	var a = {1:{2:3,4:5}, 2:"sdfd", 3:{"a":3, "d":"e"}};
	var b = cp(a);
	console.log(b);

9、另一种深度复制

	function cp(obj) {
	
		var map = new Map();

		function copy(object){			
			var _object = map.get(object);	

			if(_object) {
				return _object;
			}
			_object = {};						
			map.put(object, _object);
			for(var i in object) {

				if(object.hasOwnProperty(i)) {					
					var d = object[i];	
					if(d && typeof d === "object") {
						_object[i] = copy(d);
					} else {
						_object[i] = d;
					}
				}
			}					
			return _object;
		}
		return copy(obj);
	}
	//Test 1
	var c = {"name":"qhairen"};
	var a = {1 : c, 2 : "sdfd", 3 : c};
	alert(a["1"] == a["3"]);
	var b = cp(a);
	console.log(b);
	alert(b["1"] == b["3"]);

	//Test 2	
	var c = {"name":null};
	var d = {"age": c};
	c.name = d;
	console.log(c);
	alert(c == c.name.age);
	var e = cp(c);
	console.log(e);
	alert(e == e.name.age);	

=====================Map的代码见另一篇文章: JS中的Map简单实现 


10、js中,new操作符的工作原理

  1. 新建一个对象,instance = new Object();
  2. 设置原型链,instance.__proto__ = F.prototype;
  3. 让F中的this指向instance,执行F的函数体
  4. 判断F的返回值类型:
          如果是值类型,就丢弃它,还是返回instance,如果是引用类型,就返回这个引用,替换掉instance。如果没有return,相当与return undefined,undefined是值类型,因此丢弃它。如果返回this,它就是instance,可写可不写。引用类型指的是函数、数组、对象

ps:对instance并不需要设置它的construct属性,这个属性在instance的原型中。
console.assert(!p.hasOwnProperty("constructor"));
console.assert(F.prototype.hasOwnProperty("constructor"));

而且,任意一个新函数在创建时,原型的constructor就已经设置好了。
var G =  function(){};
console.assert(G.prototype.hasOwnProperty("constructor"));
console.assert(G.prototype.constructor === G);
	function G() {	
		this.age = 26;
	}
	
	function F() {
		this.name = "qhairen";
		
//		return 1;
//		return 1.2;
//		return true;
//		return "dsfds";
//		return null;
//		return undefined;
//		return this;
//		return NaN;
//		return Infinity;            //上面全部返回F对象
//		return [1, 2, 3];           //返回数组
//		return new G();             //返回G对象
//		return function(){alert(1);};   //返回函数
	}
	
	
	var f = new F();
	console.dir(f);
	console.assert(!f.hasOwnProperty("constructor"));
	console.assert(F.prototype.hasOwnProperty("constructor"));

	console.assert(G.prototype.hasOwnProperty("constructor"));
	console.assert(G.prototype.constructor === G);
	
	
	F.prototype = new G();
	var f = new F();
	console.dir(f);



var f = new F();
F.prototype = new G();
alert(f instanceof F);                            //false
alert(f.__proto__ === F.prototype);    //false
console.dir(F.prototype);


F.prototype = new G();
var f = new F();
alert(f instanceof F);                                //true
alert(f.__proto__ === F.prototype);        //true
console.dir(F.prototype);


11、js中var o = f();和var o = new f();的区别?

var o = new f();

相当于

         var o1 = Object.create(f.prototype);

         var r = f.call(o1);

         var o = (_.isObject(r) ? r : o1);

而普通的函数调用var o = f();通常o会得到undefined而且属性会写到window上去。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值