”JavaScript 秘密花园“ 学习笔记 :
来源:互联网 发布:怎么搞垮一个淘宝店 编辑:程序博客网 时间:2024/05/01 05:48
前言 :
用来一年的JS,看了
JS-Garden
,挖过的坑,踩过的坑,以及编程的习惯…学到了!!!
1. 对象
1 .除了null和undefined外,所有变量都可当做对象使用;eg:
1..toString();false.toString();var func = function(){alert('test')};func .toString();
2 . 对象属性的访问方式(两种:对象.属性,对象[‘属性’]),属性名为JS关键字或存在空格,后者同样有效;
3 . 删除对象属性的唯一方法 delete,undefined 和 null不能删除属性,只是移除值
delete(obj.pro);
4 .原型 (父代的显式原型属性存在于子代的隐式原型中
(继承)
)
/*1.创建对象Func_01,并自定义原型中的属性*/ function Func_01() { this.value = 42; } Func_01.prototype = { method: function() {} }; /*2.创建对象Func_02,并设置其prototype属性为Func_01的实例*/ function Func_02(){}; Func_02.prototype = new Func_01(); Func_02.prototype.new_prop = 'new property'; /*3.Func_02 继承Object中的constructor,将constructor更改为Func_02*/ Func_02.prototype.constructor = Func_02; /*Func_02的显式原型中包含value,new_prop和constructor属性, 隐式原型中则是继承了Func_01的显式原型prototype的属性,如:method*/ /*4.创建Func_02实例,观察其原型链*/ var target = new Func_02(); /*target的显示原型prototype 为空, 但其隐式原型_proto_继承了Func_02和Func_01的显式属性prototype*/
5 .
hasOwnProperty()
,判断对象的自定义属性,非原型链上的属性,检查对象属性的唯一可用方法
。
var func01(){};func01.prototype.name = 'ztx'; //在func01原型中定义name属性var test = new func01();test.selfPrototype = undefined; //自定义属性test.name; //'ztx'test.selfPrototype; //undefinedtest.hasOwnProperty('name'); //false 原型链上的属性test.hasOwnProperty('selfPrototype'); //true 自定义属性
2. 函数
1.普通函数声明
func01(); //js引擎将所有变量声明放入global作用域,func01() 执行时已被声明并创建;function func01(){ alert('this is func01');}
2.匿名函数赋值表达式
js
func02; //undefined ,此时func02被声明,但未定义,所以是缺省值
func02(); //未定义类型,赋值操作在运行到该行时才执行,所以不是function 类型,即 typeError :类型错误
var func02 = function(){
alert('this is func02');
}
func02(); //正确位置
3.命名函数赋值表达式`
var foo = function bar() { bar(); // 正常运行,函数名在函数内部总是可见}bar(); // 出错:ReferenceError,bar()已经赋值给了foo()函数;
4.
this关键字
: 五种不同的情况,this指向各不同;五种情况 指向 全局范围内this
指向全局对象 函数调用时 全局作用域中,定义函数并调用时,fun();等同于this.fun();this
指向全局 方法调用时this
指向调用该方法的对象;function show(){return this.name;} 调用构造函数时 在函数内部,this
指向新创建的对象 显式设置时 obj.call()/obj.apply();当函数中指定对象后,默认的this
则被显式设置了
* 注:
JavaScript中函数和方法的区别
// ******************构造函数(见第六点)******************function objA(name,age){ if(name!=null&&age!=null){ this.name = name; //this 指向新创建的对象 this.age = age; }else{ this.name = "wyy"; this.age = 20; }}objA.prototype.showName = function(){ alert(this.name);}var obj01 = new objA();obj01.name;obj01.age;obj01.showName();objA.prototype.showAge = function(){ alert(this.age);}obj01.showAge();//20, 对象objA新增新的方法后,重新生成实例var obj02 = new objA('ztx',24);obj02.name;obj02.age;obj02.showName();obj02.showAge();//******************显式设置this******************var test = 'wyy';var obj3 = { test:'ztx'}function show(){ alert(this.test);}show();show.call(obj3);//this 由window被显式设置为obj3//******************将方法进行表达式赋值后,this的动态变化******************var obj3 ={name:'obj3'};var foo = {};foo.method = function(){ var obj1 = this; //this指向 foo,赋值表达式之后,指向window function test(){ obj1; var obj2 = this; //this 指向window,调用call方法后,指向obj3 }; test.call(obj3);};foo.method();//this 指向 方法的调用者:foovar test = foo.method;test(); //this 指向window
5 .闭包与引用
闭包:在当前作用域中,存在着对外部作用域变量的引用,外部变量的值在函数执行之后也不会被内存回收。当前作用域总是能够访问外部作用域变量;
通过
函数
创建闭包
,因为函数
是JS中唯一拥有自身作用域
的结构,没有块级作用域
//demo_01: //自执行匿名函数中传参i,从而获得外部作用域变量i的引用for(var i=0;i<10;i++){ (function(e){ setTimeout(function(){ console.log(e); },1000); })(i); }
- 作用域中的
变量提升
—- hoisting (参考博客园JackWang-CUMT的博客,thanks)
作用域中的所有变量的声明(不包括赋值),都会被置顶。
//自运行匿名函数中的 var myvar ='内部变量值',在编译解释的时候会被提升到该函数的顶部,即//var myvar = '变量值'; //(function() { //var myvar; // console.log(myvar); // 所以此处为 undefined // var myvar = '内部变量值'; //})(); var myvar = '变量值'; (function() { console.log(myvar); // undefined var myvar = '内部变量值'; })();
6.构造函数
-
- 通过
new
关键字调用的函数都被认为是构造函数; - 当构造函数没有显式
return
时,则隐式return
新创建的对象,即有return
的构造函数,得到的是返回的对象,没有return
的构造函数,得到的是创建的对象; - …..
- 通过
3.数组相关
使用普通for循环来遍历数组,for in 遍历可能导致错误,并降低性能;
使用普通for循环是,提倡缓存数组的长度,即:
for(var i=0, len=array.length;i<l,i++){}
Array
构造函数,==推荐使用数组字面语法,即:[ ] 来新建数组==,使用构造函数new Array()
创建数组时,当Array()
中传入一个数字
参数时,将设置数组的length
属性,数组未被创建;修改array.length=10属性,减小array.length=5则对数组进行截断,将array.length=10增加为原长度后,数组length属性改变,其他不变,数组没有新增索引,
array[5]~array[9]; //undefined5~9 in array; //falsearray[5] = undefined; //自定义新索引5 in array ; //true
4.类型
1.比较
等于操作符 ==
与严格等于操作符 ===
,判断是否相等时==应使用后者==,前者在比较时进行强制类型转换
,后者则不会,如需转换,应显式转换;- 比较运算中,若有一个操作数为对象,则比较的不是值是否相等,而是判断是否是同一个对象。
- 使用
Object.prototype.toString
来检测一个对象的类型2.typeof / instanceof 操作符
5.核心
1.eval()执行时的作用域:(不要使用eval)
当前作用域:eval() 被直接调用,且调用函数就是eval自身
全局作用域: 以上除外
2.undefined 和 null
1.undefined 这个变量不是常量,不是关键字,是一个可以被轻易覆盖的值;
2.Null,另一种数据类型
3.JS分号自动插入,对于没有分号的代码,分号自动插入有时会改变代码行为或编译出错。
6.其他
JS引擎的计时策略和单线程运行模式,无法确保
setTimeout()
被准时调用;使用
setTimeout
/setInterval
函数时,第一参数不用使用字符串,使用匿名函数;在调用定时器函数时,==使用字符串形式时==,不要向回调函数中传参
setTimeout('foo(1,2,3)',1000);//不推荐setTimeout(function(){ //使用匿名函数实现上述功能 foo(1,2,3);},1000);
Version_01 17/09/14 待续。。。
- ”JavaScript 秘密花园“ 学习笔记 :
- 《Javascript秘密花园》学习笔记(上)
- 《Javascript秘密花园》学习笔记(中)
- 《Javascript秘密花园》学习笔记(下)
- 《Javascript秘密花园》学习笔记(终)
- JavaScript 秘密花园
- JavaScript 秘密花园
- JavaScript 秘密花园
- javascript 秘密花园
- JavaScript 秘密花园?
- JavaScript 的秘密花园
- JavaScript 秘密花园
- Javascript秘密花园
- Javascript秘密花园[摘录]
- JavaScript 秘密花园
- javascript秘密花园
- javascript的秘密花园
- javascript秘密花园读书笔记
- 腾讯云数据库CDB技术演进之路
- PHP的单例模式
- 关于tableview的单元格点击无响应或者最后一行显示不全
- 每天一个linux命令(2):cd命令
- Android 编译时注解
- ”JavaScript 秘密花园“ 学习笔记 :
- 使用 qemu 搭建内核开发环境
- 多线程-局部变量和成员变量
- 超键、候选键、主键、外键区别?
- Oracle导出数据字典SQL语句
- LeetCode 第一题
- js模板jsTpl
- mysql集群——(三)多管理节点
- 关于Android打log