前端基础总结之JS(上)

数据类型:
基本数据类型:Number、String 、Boolean、Null和Undefined
按值访问,可以操作保存在变量中实际的值,存放在栈(stack)内存中的简单数据段,数据大小确定,内存空间大小可以分配。
引用数据类型:对象,包括函数,数组,日期等
存放在堆(heap)内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。
创建一个引用数据了类型时,会在堆内存创建一个对象,并且在栈内存中创建一个对对象的引用(即引用类型在栈内存中存放的只是该对象的访问地址,而在堆内存中为这个值分配空间存储)
当我们需要访问引用类型(如 对象,数组,函数 等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

关于堆和栈:
堆:用于引用类型分配空间,运行时动态分配内存,存取速度慢
栈:存放一些基本类型的引用,栈内数据可共享,但栈中的数据大小和生存期必须确定。

深拷贝和浅拷贝
浅拷贝(父元素与子元素关联):
当我们使用对象拷贝时,如果属性是对象或数组时,这时候我们传递的也只是一个地址。因此子对象在访问该属性时,会根据地址回溯到父对象指向的堆内存中,即父子对象发生了关联,两者的属性值会指向同一内存空间。对象中的基本数据类型不会关联父元素。
深度拷贝(无关联):
既然属性值类型是数组和或象时只会传址,那么我们就用递归来解决这个问题,把父对象中所有属于对象的属性类型都遍历赋给子对象即可。


null和undefined
null表示"没有对象",即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
undefined是访问一个未初始化的变量时返回的值,而null是访问一个尚未存在的对象时所返回的值。因此,可以把undefined看作是空的变量,而null看作是空的对象。

基本包装类型(Wrappers)
Number, String, Boolean, 它们是特殊的引用类型,既与其他的引用类型相似,同时又具有与各自的原始类型相应的特殊行为。
Number(1)是对1执行Number类包装,会对传入的参数去两侧空格,去掉引号,如果是纯数字,则返回纯数字,否则返回NaN,(1=== Number(1))

包装类型和引用类型的区别
引用类型和包装类型的主要区别是对象的生存期。
使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行期间,然后立即被销毁,这也意味着我们不能在运行时为基本类型添加属性和方法。

prototype和原型链:
Prototype是原型属性,是一个指针指向一个对象,该对象包含可以由特定类型的所有实例共享的属性和方法。通过构造函数生成对象实例时,会将对象实例的原型指向构造函数的prototype属性。每一个构造函数都有一个prototype属性,这个属性就是对象实例的原型对象。

__proto__属性
对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。所有对象的__proto__都指向其构造器的prototype。
__proto__ 与 prototype
显式原型的作用:用来实现基于原型的继承与属性的共享。
隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这
个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。

constructor属性:
prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。
由于constructor属性是定义在原型(prototype)对象上面,意味着可以被所有实例对象继承。
constructor属性的作用
a:分辨原型对象到底属于哪个构造函数
b:从实例新建另一个实例
c:调用自身的构造函数成为可能
d:提供了一种从构造函数继承另外一种构造函数的模式
e:由于constructor属性是一种原型对象和构造函数的关系,所以在修改原型对象的时候,一定要注意constructor的指向问题。
    解决方法有两种,要么将constructor属性指向原来的构造函数,要么只在原型对象上添加属性和方法,避免instanceof失真。

原型链(prototype chain)的特点:
    a:读取对象的某个属性时,JavaScript引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。
    b:如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overiding)。
    c:一级级向上在原型链寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链。

作用域和this:
this代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。this指的是,调用函数的那个对象。

this的值取决于调用的模式,有四种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式
1)构造函数的调用--this引用的是所生成的对象
2)方法调用--this引用的是接收方对象
3)apply或call调用--this引用的是有apply或call的参数指定的对象
4)其他方式的调用--this引用的是全局对象

this的指向:
 情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window。在严格版中的默认的this不再是window,而是undefined。
 情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
 情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
情况4:new关键字会创建一个空的对象,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。

当this碰到return时
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
虽然null也是对象,但是在这里this还是指向那个函数的实例

闭包
闭包可以解决函数外部无法访问函数内部变量的问题。
闭包的特点不只是让函数外部访问函数内部变量这么简单,还有一个大的特点就是通过闭包我们可以让函数中的变量持久保持。
闭包的理解:
  所谓的闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰。
闭包的创建:
  一个函数中嵌套另外一个函数,并且将这个函数return出去,然后将这个return出来的函数保存到了一个变量中,那么就创建了一个闭包。
示例:
var lis = document.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
(function(i){
lis[i].onclick = function(){
console.log(i);
}
})(i)
}

闭包的特点:
使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
f2可以读取f1中的局部变量,那么只要把f2作为返回值,就可以在f1外部读取它的内部变量。f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
闭包就是能够读取其他函数内部变量的函数,可以简单理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

apply和call
apply和call都可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象。call/apply方法最大的作用就是能改变this关键字的指向
apply:最多只能有两个参数——新this对象和一个数组argArray
call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。

Javascript垃圾回收方法
标记清除(mark and sweep)
这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。
垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了

引用计数(reference counting)
在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
在IE中虽然JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的,也就是说只要涉及BOM及DOM就会出现循环引用问题。

内存泄漏的产生:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束
1)意外的全局变量引起的内存泄露
2)闭包引起的内存泄露,闭包可以维持函数内局部变量,使其得不到释放。
将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对dom的引用。
3)没有清理的DOM元素引用,DOM清空或删除时,事件未清除导致的内存泄漏
4)被遗忘的定时器或者回调
5)子元素存在引起的内存泄露
6)IE7/8引用计数使用循环引用产生的问题
function fn(){
var a={};
var b={};
a.pro=b;
b.pro=a;
}
fn()执行完毕后,两个对象都已经离开环境,在标记清除方式下是没有问题的,但是在引用计数策略下,因为a和b的引用次数不为0,所以不会被垃圾回收器回收内存,如果fn函数被大量调用,就会造成内存泄漏。

数组和对象的原生方法
pop,pushshift,unshift,sort,slice,splice,join,split,reverse,concat,indexOf ,lastIndexOf
动态事件绑定
DOM2级事件规定的事件流的三个阶段:捕获,目标,冒泡
1,DOM0级事件处理程序
使用DOM0级方法指定的事件处理程序被认为是元素的方法,处理程序是在元素的作用域进行的,程序中this是引用的是当前元素。
首先获取操作元素的引用,然后指定on事件。
2,DOM2级事件处理程序
事件是在冒泡阶段被触发,与DOM0级方法一样,这里添加的事件处理程序也是在其依附的元素作用域中运行,使用DOM2级添加事件处理程序的好处是可以添加多个事件处理程序
addEventListener(type,function(e){ },false);
3,IE事件处理的程序(作用域是全局的)
attachEvent('on'+type,handler);
attachEvent('on'+type,function(){handler.apply(el);} //保持作用域一致
detachEvent()
添加多个事件处理程序后执行顺序相反,先执行后添加的事件。this===window

事件代理
事件代理(Event Delegation),又称之为事件委托。是 JavaScript 中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。

XML和JSON
主要差异:
XML 被设计为结构化、传输和存储数据,其焦点是数据的内容。XML 是不作为的。
HTML 被设计用来显示数据,其焦点是数据的外观。

XML:扩展标记语言 (Extensible Markup Language, XML),可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
<1>.XML的优点  
A.格式统一,符合标准;  
B.容易与其他系统进行远程交互,数据共享比较方便。
<2>.XML的缺点  
A.XML文件庞大,文件格式复杂,传输占带宽;  
B.服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;  
C.客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;  
D.服务器端和客户端解析XML花费较多的资源和时间。

JSON定义JSON(JavaScript Object Notation)一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。
<1>.JSON的优点:  
A.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;  
B.易于解析
C.支持多种语言    
D.因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。
<2>.JSON的缺点  
A.没有XML格式这么推广的深入人心和喜用广泛,没有XML那么通用性;  
B.JSON格式目前在Web Service中推广还属于初级阶段。

1、XML 存储数据,存储配置文件等需要结构化存储的地方使用;
2、数据传输、数据交互使用JSON

猜你喜欢

转载自blog.csdn.net/qq_30422457/article/details/80973941
今日推荐