JavaScript高级程序开发3笔记
Js对象
注意:js基本数据类型不是对象,但是“abc”.match()这种,可以调用对象的方法,是因为调用方法是临时产生了一个wrapper的包装对象,this指向它;
Js对象属性的配置
Configurable: 构造,是否能够delate该属性,修改该属性特征
Enumerable: 该属性是否能够被枚举(如for in ,JSON.stringify转字符串)
Writable: 是否为只读
Value: 设置值
Object.defineProperty(obj,”key”,{
})
而defineProperties是修改多个对象属性的方法。
Object.getOwnPropertyDescriptor(obj,”key”)返回该属性的描述符对象。
propertyIsEnumerable(propertyName):是否可枚举
只要设置了Configurable:false,则这个属性无法改变配置,即无法再次用从configurable设置其表征
原来在对象里声明以key-value 形式的属性,其默认的描述符都为true,而在Object.defineProperty中设置的不初始化都为false;configurable为false的属性无法再次配置属性(会报错);
访问器属性:有且仅有四个属性。不初始化为false或者undefined。
Object.defineProperty(obj,”year”,{
Configurable:true,
Enumerable:true,
Set:function(){},
Get:funciton(){}
})
变量、作用域、内存问题
Typeof(a)==undefined;
这有两种情况,1:未赋值,或者调用对象的属性(如var obj={}, obj.a);
2:未定义,会报错。
JavaScript不能直接访问内存中的位置,也即是说不能直接操作对象的内存空间,操作对象时,实际上操作的是对象的引用而不是实际的对象。也就是说直接比如:var a={name:”tom”};
Var b=a; a=null; b不会被清空,是a这个指针被清空。
jQuery中复制对象的方法var b = $.extend(true, {}, a);
Js中求值策略:
但是请注意!!: js中基本类型,是按值传递,而对象,也就是引用类型并不是按引用传递,而是按共享传递(call by sharing),也就是说操作对象属性时,可以相互影响,而重置这个对象时,就相当于在堆中新建了一个对象,无法影响另一个引用。
变量类型:基本类型和引用类型;
基本类型(简单数据类型:直接把值存在栈内存中,值的大小是固定的):Undefinded , Null , Boolean , Number ,String
复制给另一个变量过程是:直接复制
引用类型(复杂数据类型:栈中对象在堆中的地址):对象的形式
以构造函数声明的都为引用类型,如var a=new String(“abc”); 有内部属性,length:3 , 0:“a”,1:”b” , 2:”c”
赋值给另一个变量的过程是:赋予指针,指向堆中的对象
参数传递:ECMAScript中所有函数的参数都是按值传递,即使是引用类型的变量类型,也是按值传递,意思是说:会把这个值在内存中的地址复制给arguments对象的一个元素,也就是在栈中复制了一个带有这个对象在堆中的地址,但是这个局部对象和外部的对象的引用是指向堆中同一个对象,因此在局部环境中修改这个对象的属性仍然对外部的对象有影响。
例子:var person={
name:"tom",
age:10
}
function kk(pn){
pn.age=11;
pn.sex="man";
Pn=new
}
kk(person)
console.log(person)
Person 并没有清空;
Type of :
在检测基本类型是,这个方法非常好用(除了null会返回object);
但是当检测引用类型时候,就会返回object和function当想要知道它是什么类型的对象时候无用。
正则比较特殊,Safari 5 和 chrome 7之前检测为 function
Instanceof: person instanceof Object true(当然只要是引用类型这会一直为true) ...是否是..的实例
执行环境
含义:执行环境定义了变量或函数有权访问的其他数据。
每个执行环境都有与之关联的变量对象(环境中定义的变量和函数都保存在这个对象中),我们编写的代码无法访问这个对象,但是解析器在处理数据会在后台使用它。
在某个执行环境中的代码执行完毕,该环境被销毁。
每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,而在函数执行完毕,栈将其环境环境弹出,把控制权返回给之前的执行环境。
变量对象的作用域链(scope chain):如果是函数,则将其活动对象作为变量对象,一开始只有一个arguments对象。
延长作用域链:
With:如 with(expresion){} 将expresion添加到变量对象的前端,在{}里可以访问到expresion的方法和属性;
Try{}catch(err){} :会创造一个新的变量对象(err对象)在变量对象的前端。
垃圾收集
垃圾收集器会按照固定的时间间隔或者代码执行中预定的收集时间周期性释放内存;
垃圾收集器会追踪变量是否无用,对不再有用的变量打上标记,以便将来释放其内存。
标记无用变量的策略通常有两种:
1标记清除(mark-and-sweep)
会给所有变量加上标记,然后他会去掉环境中的变量以及被环境中变量引用的变量,之后加上标记的变量就是应该清除的变量。
2.引用次数(reference counting) IE采用两种方式并存
跟踪每一个值被引用的次数,如果引用次数为0,则清除这个值。(但是循环引用将会导致引用次数永远不能为0,)
内存管理
JavaScript中有一个最主要的问题是分配给Web浏览器的可用内存数量通常比桌面程序少(处于安全方面的考虑,防止JavaScript的网页耗尽所有系统内存导致系统崩溃)
内存限制不仅影响给变量分配内存,同时会影响调用栈以及在一个线程中能够同时执行的语句数量。
因此优化内存:执行中的代码最好只保存必要的数据,一旦数据不再使用,最好null清空(解除引用),而局部变量会在它们离开执行环境是自动被解除引用。
解除引用的真正目的是让值脱离环境,以便垃圾收集器下次将其回收。
引用类型
Object
对象自变量实际上不会调用Object构造函数,
对象自带的方法
toString() valueOf() toLocalString() toSource()
Array
字面量也不调用构造函数
检测数组: ... Instanceof Array 这是只有一个全局执行环境有效运行,如果网页有多个框架,就存在两个以上不同版本的Array构造函数。
最保险的是ECMAScript5 Array.isArray(); (ie9)
当然Object.prototype.toString.apply(arr)---->[object Array]最好,兼容性最好,当然这只能对 对象检测,如果是简单数据,则会像对 对象那样处理
Push pop shift unshift splice sclice
迭代方法:(除了foreach都对原数组无影响)
判断
Every 每一项返回true,则最终返回true IE8+
Some 有一个返回true,则最终返回true IE9+
过滤
Filter 返回true的组成数组 IE9+
处理
Foreach 无返回,处理结果组成数组 IE9+
Map 返回值组成数组 IE9+
EMACScript中新增:reduce(function(pre,cur,index,array){}) reduceRight()---> 第一次迭代发生在第二项,每一个返回的值都作为pre
Function
由于函数名相当于指针,所以没有重载,函数名相同就是一个函数
caller属性:表示调用当前函数的函数的引用。如果是全局中调用,则为null
属性length:形参个数
包装类型(Boolean Number String)
“abc”.subString(2)
内部实际等同于运行了
Var s1=new String(“abc”);
s1.subString(2);
S1=null;
String方法
Trim()返回一个副本,而不是本身
slice(start,end)
Substring(start,end)
Substr(start,num)
第一个参数为负数slice、substr(负数+length),substring (负数转换为0)
第二个参数为负数slice(负数+length),substring、sbustr (负数转换为0)
Substring()是不能以负数起始的
布尔类型的对象和数字类型的对象,重写了valueof--->true||10, tostring---->”true”||”10”
indexOf(str,start)
lastIndexOf(str,start)搜索方向从后向前
tolowerCase() toUperCase()
Match(pattern); 类比exec()非全局下返回一致,而全局下根据lastIndex搜索下一个匹配值,并返回新的lastIndex
Search(str||pattern); return:position||-1 ;
Replace(str||pattern, str) return: 全局下返回所有匹配的字符串数组
Replace(str,”word($)”)
Replace(str||,function(match,pos,originalText){})
原型
任意一个函数都有一个内置的原型对象prototype,它里面内置有有两个属性__proto__ 和constructor,这个constructor指向这个函数。(当然,每个js对象都有__proto__对象,而不仅仅是函数)
注意:当使用如 a.prototype.name=”tom”是给原型对象添加属性,而a.prototype={}重置了prototype对象,__proto__ 和constructor被清空了。所以
function a(){}
a.prototype={name:"tom"};
var b=new a();
console.log(b.constructor) //得到的是第二层原型链中的constructor
a.prototype===b.__proto__;
a.prototype.isPrototypeOf(b);
b.hasOwnProperty(“name”);
Object.getPrototypeOf(b);
Object.getOwnPropertyNames(a.prototype) 获取原型对象keys数组 等同于Object.keys(a.ptototype) 同时Object.keys(b)返回实例属性
New 运算符做的事情:
1.初始化对象; var obj={};
2.Obj.__proto__ =a.prototype;
注意:也就是说比如var a =function(){a.prototype={}} ; var b=new a(); 该b.__proto__为原来的,而后更改a.prototype为{},因而b.__proto__与a.prototype不相等,导致a.ptototype.isPrototypeOf(b)为false;
而写在外部,则不会有这个问题,但是仍然会出问题,b.constructor不对,所以可以在外部设置a.prototype.constructor=a;即可,但是这样一来,constructor就可以被枚举了,可以用Object.defineProperty()表示;
3.a.call(obj) :构造obj,初始化obj
In操作符:
1.单独使用
Alert(“name” in b); true -->这要是b的属性,都可以返回true
2.for in
实例和原型之间是松散链接,即是用指针指向原型;
原型对象的缺陷:
如果原型对象的属性中有应用类型,比如:
Var b.ptototype={
People:[“jim”,”tom”]
}
这样修改一个实例的people属性,会影响所有的people属性。如果是重写,则无影响。
在构造函数中,一旦像工厂模式这样直接return一个对象,就会new调用构造函数时的值(这样构造出来的对象会被覆盖),但是如果直接return简单数据类型(null undefined/什么都不写 string number boolean),则不会对返回的实例对象有任何影响。
函数
函数声明
Function a(){} --->a.name=a
函数表达式(实际上这种也会提升,但是没有赋值,也就是说变量对象在解析时,所有变量和函数都会被推入,但是变量都没有赋值)
Var a=function(){},匿名函数; name值为空
注意:无效语法 if(condition){funtion a()}{}else{function b(){}}---->这会导致错误,大多浏览器会忽略condition,直接返回第二个声明,而ff表现正常
参数
arguments{}----->都是内部属性,0:10, 1:24 , 2:32 (可配置,可枚举,可写);length(可配置,不可枚举,可写) ; callee:对该函数的指针(可配置,不可枚举,可写)
Function a(num1,num2){} a(1,2,3)
在函数内部argument[i] 与num1,num2的值是相等的,但是它们访问的内存空间不是相同的,它们的内存空间是独立的,只是值同步。
注意:在非严格模式,arguments[i]和相对应的num的值是相互影响的,修改其中一个,另一个也会被修改,而严格模式,修改其中一个,另一个不受影响。同时严格模式不允许重写arguments对象(直接报错)。而非严格模式可以修改,但是num 不受影响。
函数指针
arguments.callee
没有重载:
由于没有函数签名(接收参数的类型和数量),所以没有重载。
属性:length prototype call apply caller
递归函数
递归函数内部使用arguments.callee替代函数名更安全,它是一个指向当前函数的指针
----->当在外部改变该函数时候,如var other=diguifunction; diguifunction=null; 不会出错
闭包
罗列闭包情景
Function name(){
return function(){}
}
Function a(){
Var arigin=arguments.callee;
This.gouzao=function(){
Return arigin
}
}
闭包:指有权访问另一个函数作用域里的变量的函数;
记住:当你想在当前的一个未运行的函数表达式是中输入变量(这个函数在以后你调用的时候可能这个变量已经被以前的操作给修改了,我可以管这叫即时输入变量的值),一定要使用一个闭包。
匿名函数
匿名函数的执行具有全局性:
所以在调用一个返回匿名函数的情况下,匿名函数中的this会指向window。
This
var obj={
a:function(){
alert(this)
}
}
(obj.a=obj.a)()------------>window ,赋值语句,
执行优先级
语句执行==前置递加,递减 >后置递加,递减
前置递加,递减与语句执行优先级相等,因而以下合理
var a=10;
var b=a++;
alert(b); // 10
类型转换
手动类型转换
1.value.toString() ------->不能转换null 和undefined ,而且对纯对象会转化为【object Object】,对数字 num.toString(2)
2."" + value
3.String(value) 对纯对象会转化为【object Object】
4.JSON.stringify() 对json对象进行转换
5valueOf() ------->不能转换null 和undefined,返回数字,字符串,对象
6.Typeof
7.Number()
8.ParseInt() parseFloat() “12ab”---->12
强制类型转换
1.对某个值进行计算时候(++,--,+,- ,……)
字符串转换(num ,NaN)
Boolean(0, 1)
对象(先调用valueOf)
+ 和 —放在前面,类型转换(—转负数,类型转换)
反码:
补码:反码+1;
位操作符(直接对二进制按位进行操作):数值表示的最底层的操作,因而速度最快
对NaN和Infinity进行位操作,这两个都会作为0处理
按位非NOT : ~ 反码
按位与AND: & 返回对其 的位上的都为1(或0)的返回1(或0),其他为0
按位或OR: | 都为0 返回0
按位亦或XOR: ^ 有且仅有一个1,返回1
左移: num << 5 向左移动5位
右移(有符号位): num>> 5 向右移动5位(在符号位右边填充0)
无符号位右移 :num>>> 5 在一开始填充0,对负数有影响
逻辑操作符
! !!等同于Boolean()
对 !{}:false
!””:true
!”ab”:false
!0:true
!NaN:true
!undefined:true
!null:true
!Infinity:false
&&与------》(可以理解找false返回,找不到返回第二个)
Var reslult=a && b;
a求值不为false是才返回b,a 为false时返回a
||或----》(可以理解为找true返回,找不到返回第二个)
Var result=a||b;
a求值不为true才返回b,a为true是返回a
+ 中如果两个中有一个不是数字 那么:对象、数值、布尔值、Infinity先调用toString(),undefined,null用String()特殊情况:数字+undefined:NaN ; 5+null:5 ;数字+Infinity:Infinity
- 中如果有一个操作数为字符串、布尔值、null 、undefined先调用Number()
如果有对象,则调用valueOf()
Number(“120ab”)--->NaN; 即“120ab”-10 :NaN
关系操作符
字符串比较:字符编码比较(比较首字母)”23”<”3” 是true
如果有一个数字,另一个要转化为数字
对象:valueOf()如果没有valueOf() 则用toStirng();
值相等(==)先转化再比较(两个对象比较时,仅有指针指向同一个对象时返回true)
特殊:null与undefined相等(虽然Number(
undefined):NaN 而Number(null):0)
全等(===)直接比较
逗号,一个语句中执行多个操作
If(expresion) Boolean(expresion)转换
语句
标签lable
outermost:
For(var i=0;i<12){
For((var i=0;i<12;i++){
continue outermost; //continue 外层循环。
}
)
Global全局
escape 和 unescape()已经废弃
encodeURI
对应decodeURI
encodeURIComponent():对任何它发现的非标准字符进行编码
对应 decodeURIConponent()
内存泄露
这种闭包,这样写,循环引用了,内部element内存无法释放。
如果程序中只需要引用dom上挂载的数据,可以直接把它提取出来,而不要直接写在事件函数里,因为这样事件对这个对象的引用不会消失,因而对象不会被回收。
模块模式
经常使用一个单例
事件
事件流
IE 的事件冒泡
Netscape Communicator的事件捕获
事件流的是三个阶段:
事件捕获阶段(规范要求这个阶段不会接收到事件,但是)、处于目标阶段、事件冒泡阶段
处于目标阶段实际上被看成冒泡阶段的一部分。
事件侦听器(事件处理程序)
有权访问全局作用域的任何代码
直接在html元素中添加事件监听有几个缺陷:
1.不利于管理开发(紧耦合)
2.Html元素显示时可能事件未添加,引发错误(可以用try{}catch()屏蔽错误)
adEventListener(“docha”,function(){},false) removeEverntListener(“docha”,function(){},false)
注意:参数中匿名函数这种形式无法取消绑定事件函数。所欲参数指向相同时才能取消,因而要用句柄的形式
事件对象
属性方法:
Bubbles 是否冒泡
Cancelable 是否可以取消事件默认行为
Current Target 事件处理程序当前正在处理事件的元素
Target 事件的目标
Trusted 浏览器生成为true,开发人员通过JavaScript创建为false
Type 事件类型
View 与事件相关联的抽象视图
Default Prevented 是否已经调用了 Prevent Default()
Detail 事件相关的详细细节
Event Phase 1:事件捕获 2:处于目标 3:冒泡阶段
Prevent Default() 取消系统默认行为
stoImmediateProipagation() 取消事件捕获或冒泡,同时阻止程序被调用
stopPropagation() 取消捕获或冒泡
创建事件对象监听:
IE8:attachEvent()
现代:addEventListener()
创建自定义事件:
IE8:
1.创建事件对象:var event=crateEventObject();
2.添加属性: event.msg=”我是fierEvent触发的”
2.触发事件 obj.fireEvent(“onclick”,event)
现代:
1.创建事件对象:var event=createEvent()
2.初始化事件对象:event.initEvent()
3.分配事件对象:obj.dispatchEvent(event)
主动触发objDom.dispathEvent()
创建事件对象 Var evt=document.createEvent(“Event”);
初始化对象evt.initEvent(“click”,true,true) 三个参数的含义eventType,canBubble,cancelable
分配事件对象 objDom.dispatchEvent()
兼容性解决方案
var dispatch = window.addEventListener ?
function(el, type){
try{
var evt = document.createEvent('Event');
evt.initEvent(type,true,true);
el.dispatchEvent(evt);
}catch(e){alert(e)};
} :
function(el, type){
try{
el.fireEvent('on'+type);
}catch(e){alert(e)}
};
Dispatch(objDom,”click”);
DOM
cloneNode(true)---true:是否复制属性
补充
具名函数
Var a=funciton b(){} //具名函数
IE8以上以及其他浏览器无法在外部访问到b(会报错),只能在内部访问到b
Var a=function(){} //匿名函数
JavaScript高级程序开发3笔记的更多相关文章
- javascript高级程序语言学习笔记
1.加法操作符(+)的用法 第一种情况,如果两个操作符都是数值,执行常规的加法计算. 第二种情况,如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来. 第三种情况,只有一个操作数是字符串 ...
- 《JavaScript高级程序设计》读书笔记--前言
起因 web编程过程使用javascript时感觉很吃力,效率很低.根本原因在于对javascript整个知识体系不熟,看来需要找些书脑补一下,同时欢迎众网友监督. 大神推荐书籍 看了博客大神们推荐的 ...
- 《JavaScript高级程序设计》学习笔记(4)——引用类型
欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第五章内容. 在ECMAScript中, ...
- 《JavaScript高级程序设计》学习笔记(3)——变量、作用域和内存问题
欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第四章内容. 1.函数:通过函数可以封装 ...
- 《JavaScript高级程序设计》学习笔记12篇
写在前面: 这12篇博文不是给人看的,而是用来查的,忘记了什么基础知识,点开页面Ctrl + F关键字就好了 P.S.如果在对应分类里没有找到,麻烦告诉我,以便尽快添上.当然,我也会时不时地添点遗漏的 ...
- 《JavaScript高级程序设计》学习笔记
系统学习JS, 从<JavaScript高级程序设计>入门,通过学习jQuery或者angularJS源码来进阶. 第1章 JavaScript简介 1.JS问世的目的是处理以前由服务器端 ...
- WeChat小程序开发-初学者笔记(一)
WeChat小程序开发学习第一天: 完成学习目标: 1.安装并了解Wechat小程序的基本环境, 2.可以利用已学知识的结合简单实现helloWorld界面. 学习过程: 1.首先在微信平台上进行相关 ...
- JavaScript高级程序设计(读书笔记)之函数表达式
定义函数的方式有两种:一种是函数声明,另一种就是函数表达式. 函数声明的一个重要特征就是函数声明提升(function declaration hoisting),意思是在执行代码前会先读取函数声明. ...
- 《JavaScript高级程序设计》学习笔记(5)——面向对象编程
欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第六章内容. 1.面向对象(Object ...
随机推荐
- WinDbug之DUMP蓝屏分析
Microsoft (R) Windows Debugger Version 6.2.8400.0 X86Copyright (c) Microsoft Corporation. All rights ...
- 极域电子教室 e-Learning Class V4 2010专业版 学生机 卸载方法
学校的机房一般都会装教师机远程控制学生机的软件.比如我们学校装的就是"极域电子教室 e-Learning Class V4 2010专业版",上课的时候直接强制全屏远控,卸载又提示 ...
- linux下的shell命令的编写,以及java怎样调用linux的shell命令(java怎样获取linux上的网卡的ip信息)
程序猿都非常懒,你懂的! 近期在开发中,须要用到server的ip和mac信息.可是server是架设在linux系统上的,对于多网口,在获取ip时就产生了非常大的问题.以下是在windows系统上, ...
- GLSL 基础量定义
GLSL语法跟C语言非常相似: 1.数据类型: GLSL包含下面几种简单的数据类型 float bool :false or ture int 向量: vec {2,3,4} 长度为2, ...
- Android - 软件自动更新的实现
转自:http://blog.csdn.net/wwj_748/article/details/8195565 接触到一个很实用的技术,那就是软件自动更新.一般开发者是通过自行在应用平台添加更新版本的 ...
- [AngularJS] ngCloak
The ngCloak directive is used to prevent the Angular html template from being briefly displayed by t ...
- 关于port的关闭——Linux
本文出自:http://blog.csdn.net/svitter 引文出自:http://bbs.chinaunix.net/thread-775649-1-1.html 1.关闭服务 servic ...
- JS来推断文本框内容改变事件
oninput,onpropertychange,onchange的使用方法 onchange触发事件必须满足两个条件: a)当前对象属性改变,而且是由键盘或鼠标事件激发的(脚本触发无效) b) ...
- ios开发——实用技术篇&Pist转模型详细介绍
Pist转模型详细介绍 关于Plist转模型在iOS开发中是非常常见的,每开一一个项目或者实现一个功能都要用到它,所以今天就给大家讲讲Plist怎么转成模型数据, 前提:必须有一个Plist文件或者通 ...
- Metadata Lock原理8
http://www.kancloud.cn/taobaomysql/monthly/67141 MySQL· 5.7优化·Metadata Lock子系统的优化 背景 引入MDL锁的目的,最初是为了 ...