总结篇-Javascript部分(绝对干货,未完待续...)

0-0.常用的四种设计模式

1.工厂模式:解决多个相似的问题;
2.单例模式:只能被实例化一次;
3.沙箱模式:自执行函数,使用闭包把内部方法暴露出来,例:
    var fn=(function(){
        function aFn(){};
        return {
            aFn:aFn
        }
    })
4.发布者订阅模式:有新消息主动推送的功能模式;

0-1.编程范式

1.命令式编程(流水式从上至下执行)
2.面向编程(函数式编程:闭包(函数组合嵌套的方式),一类函数,箭头函数)
3.面向对象式编程(OOP:原型(链式的链接对象的对象)继承(存在父子间属性函数的使用))
    优缺点: 对象函数属性排列易于理解;命令式编码风格计算机能直接快速编译;
            多实例时乱象丛生,容易修改原始值导致解析不理想化(缺点)
4.函数式编程:
    优缺点: 避免面向对象编程的缺点,自我执行理想化程度高;
            复用性良好,存在参数无参数状态,且可以高效完成算法;
            执行逻辑清晰,方便修改和优化更新;
            避免多线程冲突,逻辑混乱
            简洁度很好,易读性稍差(缺点)

0-2.写JavaScript的基本规范?

不要在同一行声明多个变量。
请使用 ===/!==来比较true/false或者数值
使用对象字面量替代new Array这种形式
不要使用全局函数。
Switch语句必须带有default分支
函数不应该有时候有返回值,有时候没有返回值。
for循环必须使用大括号
if语句必须使用大括号
for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。

1.模拟字符串去的hash值

function hashCode(str){  
    var h = 0, off = 0;   var len = str.length;  
    for(var i = 0; i < len; i++){  
        h = 31 * h + str.charCodeAt(off++);  
    }  
    var t=-2147483648*2;  
    if(h>2147483647){  
        h+=t  
    }  
    return h;  
}  

2.获取本地时间的时间戳

var timestamp=Date.parse(new Date());	//特殊存在:毫秒显示为000(不去秒以下的数值)
var timestamp=(new Date()).valueOf();
var timestamp=new Date().getTime();

3.fixed固定定位不随滚动条移动

<div class=”fixedDiv”>…</div>

.fixedDiv{
	position:fixed;
	width:1000px;
	bottom:0;
	z-index:1000;
}

window.onscroll=function(){
	var sl=Math.max(document.body.scrollLeft,document.documentElement.scrollLeft);
	document.getElementsByClassName(“fixedDiv”)[0].style.left=(-sl)+”px”;
}

4.获取指定字符串中某字符出现的所有下标

function getAllIndex(str,chars){
    var arr=[];
    for(var i=0;i<str.length;i++){
        if(str.substring(i,i+1)==chars){
            arr.push(i)
        }
    }
    return arr
}

5.监听滚动条的事件,并获取top&bottom的距离

$(window).scroll(function() {  
    var scrollTop = $(this).scrollTop();  
    var docHeight = $(document).height();  
    var windowHeight = $(this).height();
    var scrollHeight=document.body.scrollHeight;

    console.log("scrollTop:"+scrollTop);
    console.log("scrollbottom:"+(docHeight-scrollTop-windowHeight));

    if(scrollTop + windowHeight == docHeight) {    
        alert("已经到最底部了!");  
    }
});

6.-‘类继承’和‘原型继承’有什么区别?

类继承:
    实例由类继承而来(建筑图纸和实际建筑的关系),同时还会创建父类—子类这样一种关系,也叫做类的分层
分类。通常是用 new 关键字调用类的构造函数来创建实例的。不过在 ES6 中,要继承 一个类,不用 class 关
键字也可以。尽量不用类继承,除非是单一级的使用。

原型继承:
    实例/对象直接从其它对象继承而来,创建实例的话,往往用工厂函数或者 Object.create() 方法。实例可
以从多个不同的对象组合而来,这样就能选择性地继承了。主要实现手段有:委托(原型链);组合;函数式(这
个函数式原型继承不是函数式编程。这里的函数是用来创建一个闭包,以实现私有状态或者封装)

7.双向数据绑定/单向数据流的含义和区别

双向数据绑定:
    UI 层所呈现的内容和 Model 层的数据动态地绑定在一起,其中一个发生了变化,就会立刻反映在另一个
上。比如用户在前端页面的表单控件中输入了一个值,Model 层对应该控件的变量就会立刻更新为用户所输入的
值;反之亦然,如果 Modal 层的数据有变化,变化后的数据也会立刻反映至 UI 层。Angular 则是双向数据绑
定的典型。

单向数据流:
    意味着只有 Model 层才是单一数据源。UI 层的变化会触发对应的消息机制,告知 Model 层用户的目的。
只有 Model 层才有更改应用状态的权限,这样一来,数据永远都是单向流动的,其状态的变化是很容易跟踪的。
React 是单向数据流的典型。

8.jquery不常用但实用的方法

(1)位置相关
    offset()          $(“#qq”).offset()          相对浏览器窗口的位置
    offsetParent()    $(“#qq”).offsetParent()    #qq相对最近的已经定位的祖先的位置
    position()        $(“#qq”).position()        已定位的元素的position值
(2)DOM元素的包裹
    wrap()           $(“#qq”).wrap(“<div id=’qqPar’/>”) 
    wrapAll()        所有指定元素都会被包裹
    wrapInner()      指定元素的内容会被包裹
(3)删除相关
    detach()         删除了还能恢复
    empty()          删除子元素的所有东西
    remove()         删除指定元素
    unwrap()         删除指定元素的父节点,但是保留本身

9.基本类型与引用类型有什么区别?

基本数据类型: Undefined、Null、Boolean、Number、String
引用数据类型: Object, Array, Date, RegExp(正则), Function

区别:
    存储:
        基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中
        引用类型的值是对象, 保存在堆内存中. 引用类型的变量实际上是一个指向该对象的指针
    复制:
        从一个变量向另一个变量复制基本类型的值, 会创建这个值的一个副本
        从一个变量向另一个变量复制引用类型的值, 复制的其实是指针, 因此两个变量最终都指向同一个对象
    检测:
        确定一个值是哪种基本类型可以用typeof操作符
        确定一个值是哪种引用类型可以使用instanceof操作符

10.null,undefined 的区别?

undefined 表示不存在这个值    typeof undefined //"undefined"
null 一个对象被定义了,值为“空值”    typeof null //"object"

undefined :是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但是还没有定义。例如变量
被声明了,但没有赋值时,就等于undefined
null :是一个空对象, 没有任何属性和方法。例如作为函数的参数,表示该函数的参数不是对象

注意:在验证null时,一定要使用 === ,因为 == 无法分别 null 和 undefined

11.什么是闭包(closure),为什么要用它?

闭包:是指有权访问另一个函数作用域中变量的函数。
特点:
    1.创建闭包的最常见的方式就是在一个函数内创建另一个函数;
    2.利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部;
    3.使用闭包主要是为了设计私有的方法和变量;
    4.闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量;
    5.在js中,函数即闭包,只有函数才会产生作用域的概念;
特征:
    1.函数内再嵌套函数;
    2.内部函数可以引用外层的参数和变量;
    3.参数和变量不会被垃圾回收机制回收;
例子:
    var add = (function () {
        var counter = 0;
        return function () {return counter += 1;}
    })();
    add();
    //1
    add();
    //2

12.什么是伪数组

伪数组概念:是能通过Array.prototype.slice 转换为真正的数组的带有length属性的对象;
伪数组示例:
    1.arguments对象
    2.调用getElementsByTagName,document.childNodes之类的node集合
伪数组变更:
    Array.prototype.slice.call(fakeArray)转变为真正的Array对象,返回新数组而不会修改原数组

13.javascript创建对象的几种方式

1.对象字面量(最后一个key-value不添加逗号)
    var obj={
        name:"yjs",
        age:25,
    };
    优缺点:复用性较差(缺)

2.构造函数(函数名首字母使用大写,区分函数和自定义对象,可以传参的呦)
    function NewObj(){}
    var person=new NewObj();
    person.name="yjs";
    person.age="25";
    person.city="sjz";
    person.getName=function(){
        console.log("对象的名称是:"+person.name)
    }
    person.getName();
    优缺点:复用性较差(缺)

3.构造函数-含参(用this关键字定义构造的上下文属性,一般不会出现return的语句)
    function One(name,age,city){
        this.name=name;
        this.age=age;
        this.city=city;
        this.getName=function(){
            console.log("对象的名称是:"+person.name)
        }
    }
    var one=new One("yjs",25,"sjz");//实例化对象
    one.getName();
    优缺点:实例化的对象可以识别指定的类型(优);每次实例都会重新创建函数,全局变量多(缺)

4.工厂函数(内置对象,这种事最不推荐使用的)
    var per=new Object();
    per.name="yjs";
    per.age=25;
    per.city="sjz";
    per.getName=function(){
        console.log("对象的名称是:"+person.name)
    }
    per.getName();
    优缺点:所有的实例都指向一个原型,对象无法识别(缺)

5.原型
    function One(){}
    One.prototype.name="yjs";
    One.prototype.getName=function(){
        console.log("对象的名称是:"+person.name)
    }
    var one=new One();
    one.getName();
    优缺点:创建函数放在原型避免全局变量多的问题(优);不能初始化参数(缺)

6.混合(举例为:构造函数方式和原型方式的混合,以上几种可任意组合)
    function One(name){
        this.name=name;
    }
    One.prototype.getName=function(){
        console.log("对象的名称是:"+person.name)
    }
    var one=new One("yjs");
    one.getName(); 

14.谈谈This对象的理解。

1.this总是指向函数的直接调用者(而非间接调用者);
2.如果有new关键字,this指向new出来的那个对象;
3.事件中,this指向触发这个事件的对象(特殊:IE中的attachEvent中的this总是指向全局对象Window);

15.call()和apply()方法的区别

作用:都能继承另一个对象的方法和属性
区别:参数列表不一样
书写:Function.call(obj, arg1, arg2,...)    Function.apply(obj, args) 
参数:obj-要被继承的对象;第二个参数-传递的实参值
举例:
    function A(a){console.log(a)}
    function B(b,c){console.log(b+c)}
    A.call(B,10);    //10
    B.applay(A,[10,20])    //30
    

16.new操作符具体干了什么

1.创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
    var obj  = {};
2.属性和方法被加入到 this 引用的对象中。
    obj.__proto__ = Base.prototype;
3.新创建的对象由 this 所引用,并且最后隐式的返回 this 。
    Base.call(obj);

17.IE与火狐的事件机制有什么区别? 如何阻止冒泡

事件:网页中的某个操作,点击,悬停,双击,键盘事件等
机制:IE是事件冒泡、其他的浏览器同时支持两种事件模型(捕获型事件和冒泡型事件)
阻止:ev.stopPropagation();(旧ie的方法 ev.cancelBubble = true;)

18.事件委托(事件代理)是什么

原理:事件冒泡, 委托到已知的父级元素。

范围:1.js脚本动态添加的;2.不好定位的元素事件;3.相同元素过多;

例子:
    html部分:
    <ul id="list">
        <li id="li-1">Li 2</li>
        <li id="li-2">Li 3</li>
    </ul>

    js部分:
    document.getElementById("list").addHandler("click", function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.nodeName.toUpperCase == "LI"){
            console.log("li的ID是:"+e,target.id);
        }
    });

19.XML和JSON的区别

1.JSON相对于XML来讲,数据的体积小,传递的速度更快;
2.JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互;
3.JSON对数据的描述性比XML较差;
4.JSON的速度要远远快于XML;

20.哪些操作会造成内存泄漏

1.setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏;
2.闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环);
3.当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。

21.面向对象中继承实现

1.prototype原型链方式:
    function One(name){
        this.name = name;
        this.getName=function(){
            console.log(this.name);
        }
    }
    function Two(name){
        this.name = name;
    }
    Two.prototype = new One();
    var a = new One("gc");
    var b = new Two("yjs");
    a.getName();    //gc
    b.getName();    //yjs


2、call()/apply()方法
    function One(name){
        this.name = name;
        this.getName=function(){
            console.log(this.name);
        }
    }
    function Two(){
        var args = arguments;
        One.call(this,args[0]);    // One.apply(this,arguments);
    }
    var a = new One("gc");
    var b = new Two("yjs");
    a.getName();    //gc
    b.getName();    //yjs


3.混合方法(prototype,call/apply)
    function One(name){
        this.name = name;
        this.getName=function(){
            console.log(this.name);
        }
    }
    function Two(){
        var args = arguments;
        One.call(this,args[0]); 
    }
    Two.prototype = new One();
    var b = new Two("yjs");
    b.getName();    //yjs


4.对象冒充
    function One(name){
        this.name = name;
        this.getName=function(){
            console.log(this.name);
        }
    }
    function Two(name){
        this.tt = One; //将One类的构造函数赋值给this.tt
        this.tt(name); //js中实际上是通过对象冒充来实现继承的
        delete this.tt; //移除对One的引用
    }
    var a = new One("gc");
    var b = new Two("yjs");
    a.getName();    //gc
    b.getName();    //yjs

22.

猜你喜欢

转载自blog.csdn.net/qq_35892039/article/details/84942709