zoukankan      html  css  js  c++  java
  • JS方面重点摘要(二)

    1、函数声明与函数表达式

    (1)变量声明会置顶提前,但赋值仍在原地方
    (2)函数声明同变量声明一样会提前;但是,函数表达式没有提前,就相当于平时的变量赋值
    (3)函数声明会覆盖变量声明,但不会覆盖变量赋值:函数声明优先级高于变量声明的优先级;但是变量赋值以后,变量赋值初始化就会覆盖函数声明。
    2、函数arguments属性初始化:
    (1)callee:指向当前函数的引用
    (2)length:真正传递的参数个数
    (3)arguments的索引值小于传参的个数,则其值和实际传参的值是共享的;如果大于,则不共享,相方不相关,互不影响
    3、and、or、not运算符详解:
    And:(1)一个对象一个布尔,返回对象(2)2个都是对象返回第二个(3)某个是null或NaN,返回null或NaN(4)某个是undefined发生错误(5)2个都是布尔,返回布尔
    Or:(1)一个对象一个布尔,返回对象(2)2个都是对象返回第一个(3)某个是null或NaN,返回null或NaN(4)某个是undefined发生错误
    Not:(1)是对象,返回false(2)是0返回true,否则false(3)是null或NaN,返回true;是undefined发生错误
    技巧:使用2个not运算符判断变量的布尔值(第一个not返回布尔值,再第二个not取反获得变量的真实布尔值)
    4、性能优化:
    (1)避免全局查找:用局部变量存储全局变量来减少全局查找,因为全局查找需要一直找到作用域链最顶端
    (2)定时器:少用setTimeout,因为setTimeout每次都会初始化一个定时器,而setInterval只在开始的时候初始化一个定时器
    (3)字符串连接少用+=,如果需要多次对同一个字符串进行+=操作的话,可以用数组来缓存,然后join方法连接
    (4)数字转为字符串:"" + > String() > toString() > new String()
    (5)浮点数转为整型推荐用Math.floor()或Math.round(),parseInt多用于将字符串转为数字
    (6)多个变量声明,使用单var形式,以减少脚本执行时间
    (7)多使用直接量更好,如:var array = [];
    (8)使用文档碎片来构建dom结构:document.createDocumentFragment()
    (9)使用innerHTML赋值代替构建dom元素
    (10)尽量使用更准确的选择器,减少查找时间;对于获取兄弟元素,子集元素等也是一样的道理,尽量是定位更准确,避免循环
    (11)删除dom节点之前,一定要删除注册在该节点上的事件,否则会产生无法回收的内存;
    此外,在removeChild和innerHTML=""之间选择后者,因为用removeChild无法有效释放dom节点
    (12)使用事件代理
    (13)重复使用的结果,先保存到局部变量,避免多次取值的调用开销

    (14)优化循环:减值迭代更高效、简化终止条件,避免重复取值、简化循环体、使用后测试循环(while比for高效)

    (15)使用三目运算符替代条件分支

    (16)闭包里变量的释放:返回前释放不再使用的变量:b = c = null;

    5、页面重绘和回流:
    (1)页面呈现流程:html代码解析成dom树、样式解析成样式结构体、dom树和样式结构体接回呈现渲染树、浏览器根据渲染树绘制页面
    (2)回流:渲染树因为尺寸、布局、隐藏等变化而需要重新构建,称为回流
    重绘:渲染树一些元素更新属性,但只影响外观风格,不影响布局,称为重绘
    回流比将引起重绘,而重绘不一定引起回流
    (3)引起重绘和回流的操作:任何对渲染树中元素的操作都会引起回流或者重绘。回流比重绘的代价要更高,回流的花销跟渲染树中有多少节点需要重新构建有关系
    (4)聪明的浏览器,维护flush队列,一定时间批处理;
    强制flush队列的一些属性
    (5)减少重绘和回流:
    一、不要一个一个改变样式,最好改变className,若需动态改变样式,使用classText拼接样式来改变
    二、让操作的元素“离线处理”,处理完后一起更新:用createDocumentFragment或div来缓存dom元素、或先隐藏元素,处理完之后再显示元素
    三、不要经常访问会引起浏览器flush队列的属性
    四、将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位
    6、高性能web开发:dom编程
    (1)dom访问和修改:过桥例子
    (2)html集合和遍历dom,暂存dom状态信息
    (3)选择器越精确越好,缩小选择器的查找范围
    7、JSONP:
    (1)src属性拥有跨域的能力
    (2)JSONP协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据(需要包裹json数据)
    (3)ajax的核心是通过XmlHttpRequest获取非本页内容,
    而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
    8、解决跨域:
    (1)利用JSONP格式:(1)url加:&callback=?;type变为"jsonp";(2)服务器端返回数据要为jsonp格式,即:out.print(callback + "(" + json + ")");要套一层callback()
    (2)JS设置Header,实现跨域访问,服务器Action层增加Header头信息
    9、form表单实现无跳转上传文件,接收页面后台数据
    (1)form表单添加target属性,指定一个iframe的name,form表单提交后在iframe内嵌窗口接受响应,主页面就不会跳转
    (2)让后台返回一个带执行函数的script标签
    (3)另一种方法利用插件jquery-form的ajaxForm()方法
    10、怎样避免重写可能已经定义了的方法。这可以通过在定义自己的方法之前,检测方法是否已经存在。
    String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};
    当你去扩展一个Javascript方法时,这个技术非常有用。
    11、连续赋值的一个例子:
    原理可解释为“就近原则”(后面的同名变量会覆盖前面的),而且要记住这种连续赋值,后面的变量是一种隐式声明即可。
    12、数字精度丢失问题:前端遇小数计算概率大,要有这个精度丢失的意识;解决方案:把小数乘以倍数变成整数计算,再除以倍数变成原来的数。其中根据此思想封装了一个方法。

    13、判断图片加载完成:
    (1)img的onload事件
    (2)img的complete属性,为true代表加载完毕
    (3)readystatechange事件,没有onload事件和complete属性兼容性好
    14、面向对象总结
    (1)属性类型:是否可配置、枚举性(是否可for in循环)、可写性、可读性,默认true/true/true/undefined
    (2)要修改属性默认的特性,需要通过Object.defineProperty()定义
    (3)访问器属性:配置、枚举、get、set,其中get、set默认都是undefined,可以通过defineProperty来修改默认的get/set属性
    (4)创建对象的设计模式:
    工厂模式:用函数封装以特定接口创建对象
    优点:可以无数次调用函数创建相似对象;
    缺点:不能解决对象识别的问题
    构造函数模式:this加属性、new关键字调用(new执行的4个步骤)
    优点:解决了工厂模式无法对象识别的问题
    缺点:创建了功能一样的函数,造成内存浪费
    原型模式:创建每个函数的时候都有prototype属性,是一个指针,指向一个对象,该对象的用途就是包含由特定类型的所有实例共享的属性和方法
    先创建一个空构造函数,然后通过prototype属性增加属性和方法,通过new关键字调用
    优点:所有实例对象共享他的属性和方法(1、原型中的对象属性可以被实例所覆盖重写;2、通过delete可以删除实例中的属性,但是删除不了对象上的;3、hasOwnProperty()方法来确定一个属性是在原型上还是在实例上;4、简写模式,必须加constructor属性)
    缺点:对于包含引用类型的属性来说,当修改的时候就是修改所有实例共享的那个值了,所有实例都会更改
    组合使用构造模式和原型模式:构造模式定义实例属性,原型模式定义方法和共享的属性(实例所有的属性都是在构造函数中定义,而实例所有共享的属性和方法都是在原型中定义)
    动态原型构造模式:写法更高效一些
    (5)面向对象概念:一切事物皆对象;对象具有封装和继承特性;对象与对象之间使用消息通信,各自存在信息隐秘;JS基于原型来实现面向对象编程,而java基于类来实现面向对象编程
    15、构造函数继承的6种方法
    (1)构造函数绑定:使用call、apply将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:Animal.apply(this,arguments)
    (2)对象冒充:对象冒充的意思就是获取那个类的所有成员,然后调用,因为js是谁调用那个成员就是谁的
    获取所有成员:this.stu = Stu; 然后调用this.stu(name,age);
    (3)prototype模式:让prototype属性执行继承对象的一个实例。
    注意2步:
    第一步:将Cat的prototype对象指向一个Animal的实例:Cat.prototype = new Animal();(相当于完全删除了prototype对象原先的值,然后赋予一个新值)
    第二步:重新纠正构造函数指向:Cat.prototype.constructor = Cat;
    (任何一个prototype对象都有一个constructor属性,指向它的构造函数。如果没有"Cat.prototype = new Animal();"这一行,Cat.prototype.constructor是指向Cat的;加了这一行以后,Cat.prototype.constructor指向Animal。每一个实例也有一个constructor属性,默认调用prototype对象的constructor属性。这显然会导致继承链的紊乱(cat1明明是用构造函数Cat生成的),因此我们必须手动纠正,将Cat.prototype对象的constructor值改为Cat。)
    这是很重要的一点,编程时务必要遵守:即如果替换了prototype对象,那么,下一步必然是为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数
    (4)直接继承prototype模式:Cat.prototype = Animal.prototype;缺点是Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype
    (5)利用空对象做中介:
    function F(){};
    F.prototype = Animal.prototype;
    Cat.prototype = new F();
    Cat.prototype.constructor = Cat;
    F是空对象,所以几乎不占内存。这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
    (6)拷贝继承:把父对象的所有属性和方法,拷贝进子对象
    16、非构造函数的继承
    (1)object()方法:
    第一步先在父对象的基础上,生成子对象:var Doctor = object(Chinese);
    然后,再加上子对象本身的属性:Doctor.career;
    (2)浅拷贝:把父对象的属性,全部拷贝给子对象,也能实现继承。缺点是引用类型的问题
    (3)深拷贝:实现数组和对象的拷贝,递归调用"浅拷贝"即可

    17、闭包的7种形式:
    (1)函数作为返回值被返回,所以外界保持对里的引用
    (2)函数赋值,上面的变形形式,将内部函数赋值给一个外部变量,外部变量保持了对内部函数作用域的引用
    (3)函数参数传递函数的形式:(将F里的N作为参数给外界的Inner,F执行之后,外界Inner保持了对F里的引用)
    (4)立即执行函数
    (5)循环赋值
    (6)迭代器
    其实说到底闭包就是作用域外界保持了对作用域里面的引用
    18、从执行环境看闭包和垃圾回收机制
    代码一步步执行、执行环境、变量对象的活动状态和非活动状态、释放闭包引用,脱离执行环境

    19、封装组件思想:
    (1)通过$.extend去扩展原生的jquery.ajax
    得到$.ajax对象
    每次调用发送请求时定义默认的error等处理方法
    如果在调用时写了error方法就不用默认的
    利用extend扩展原生的$.ajax方法,返回最新的参数
    将最新的参数返回给ajax对象
    即:先定义默认参数、再判断用户是否自定义参数、$.extend()方法拓展默认参数列表
    (2)自定义组件步骤:
    定义jquery拓展方法,$.fn.combobox = function(options,param){}
    设置默认参数列表
    将调用时传递的参数和默认参数对象合并,拓展默认参数列表
    给元素添加默认值
    判断用户传过来的参数列表里面是否包含数据data数据集,如果包含,直接用data,不用发ajax从后台取,否则发送ajax从后台取数据
    如果传过来的不是对象,是字符串,代表调用方法

    20、不可变对象实现

    (1)const 关键字只是修改了某个变量名和其值之间的链接,而不是实际值。所以通过const声明的对象,我们依然可以改变

    (2)Object.freeze()使对象的原始属性不可变但是我们仍然可以更改嵌套对象

    (3)最终方案:采用递归freeze()所有嵌套对象

  • 相关阅读:
    您所熟悉的软件测试类型都有哪些?请试着分别比较这些不同的测试类型的区别与联系(如功能测试、性能测试……)
    你对测试最大的兴趣在哪里?为什么?
    LoadRunner分为哪三个模块?请简述各模块的主要功能。
    Django学习之视图层
    Django学习之路由层
    Django学习
    Django简介
    jQuery
    JavaScript--DOM,BOM
    前端基础之JavaScript
  • 原文地址:https://www.cnblogs.com/goloving/p/8485623.html
Copyright © 2011-2022 走看看