前端JS知识点

累加求和

function num() {
    var nul = 0,
        len = arguments.length; 
        //因为不知道传入的参数,所有直接用arguments实参列表
        //arguments是个数组,所以有length属性
    for(var i = 0; i < len; i ++ ){
        nul += arguments[i];
        //把实参类表的第 i 位累加,达到累加器的效果
    }
    console.log(nul);
}

num(1,2,3,4,5);

隐式类型转换--字符串前面加“+”号,可以转换成 number 类型

function myNumber(target) {
    return +target;
}
var num = myNumber('123');
console.log(typeof(num) + ":" + num);
//结果返回 number : 132 ;
//如果字符串是英文,这结果返回 number : NAN;

输入一个数字,得出反向汉字

function reverse() {
    var num = window.prompt("请输入");
    var str = "";
    for(var i = num.length-1; i >= 0; i --) {

    //也可以正向输出大写
    // var i = 0; i <= num.length-1; i ++

        str += reansfer(num[i]);
    // 把 reansfer方法得到的汉字传到一个空字符串里累加
    }
    console.log(str);
}

function transfer(target) {
    switch(target) {
        case "0":
            return "零";
        case "1":
            return "一";
        case "2":
            return "二";
        case "3":
            return "三";
        case "4":
            return "四";
        case "5":
            return "五";
        case "6":
            return "六";
        case "7":
            return "七";
        case "8":
            return "八";
        case "9":
            return "九";
    }
}

算阶乘用的--递归

function num(n) {
    if(n == 1 || n == 0) {
        return 1;
    }
    return n * num(n-1);
}
//解析
num(5);

//    num(5) ==> 5 * num(4);
//    num(4) ==> 4 * num(3);
//    num(3) ==> 3 * num(2);
//    num(2) ==> 2 * num(1);

预编译

JS  单线程  解释性语言  解释一行执行一行

    1.语法分析(先扫描看一遍,有没有错误)

    2.语法解析(预编译发生在函数执行的前一刻)

    3.解释一行,执行一行

暗示全局变量:

即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有。一切声明的全局变量,都是(window)全局变量。

过程:

1.创建AO对象    Activation object(执行期上下文);

2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined

3.将实参值和形参统一

4.在函数体里面找函数声明,值赋予函数体;

闭包实现累加

function add() {
    var count = 0;
    function demo() {
        count ++;
        console.log(count);
    }
    return demo;
}
    var counter = add();
    counter();
    counter();
    counter();
    counter();

立即执行函数

一经执行,立即销毁,可以有参数,带返回值

var num = (function(a,b,c){
    var d = a + b + c * 2;
    return d;
}(1,2,3))
函数声明 函数表达式
function test(){} var test = function (){}()

只有表达式才能被执行符号()执行;

使用原生JS,addEventListener,给每个li元素绑定一个click事件,并输出他们的顺序

<style>
    *{
        margin: 0;
        padding:0;
    }
    ul{
        list-style: none;
    }
    li:nth-of-type(2n){
            background: red;
        }
    li:nth-of-type(2n+1){
        background: yellow;
    }
    li{
       text-align: center;
    
    }
</style>

<ul>
        <li>a</li>
        <li>a</li>
        <li>a</li>
        <li>a</li>
</ul>

function test() {
    var liList = document.getElementsByTagName('li');
    for(var i = 0; i < liList.length; i ++) {
        (function(j){
            liList[j].onclick = function () {
                console.log(j);
            }
        }(i))
    }
}
test();

用 charCodeAt 方法计算一个字符串的字符长度

function num(target) {
    var count = 0;
    for(var i = 0; i < target.length; i ++) {
        if(target.charCodeAt(i) <= 255) {
        // Unicode 编码前255位都占一个位,255后面站2个
            count ++;
        }else if(target.charCodeAt > 255) {
            count += 2;
        }
    }
    console.log(count);
}

,逗号操作符 会把后面计算结果返回出去

 var f=(
             function f() {
                 return "1";
             },
             function g() {
                 return 2;
             }
         )();
             typeof f;
        // 返回 数字2,所有typeof f 为 unmber

立即执行函数,函数名消失问题

        var x = 1;

        if(function f() {}) { 

            //在括号里就会 函数声明就会变成表达式,变成表达式f 就消失了

            x += typeof f;    

            // 未经声明就使用的变量,放到typeof里不会报错 返回undefined,是字符串类型
         }

        x;  // 1undefined

构造函数,内部this隐式转换

 1.预编译 this -- > window

 2.谁调用的 this 指向谁

 3.call apply

 4.全局 this -- > window

                     var a = 5;
                     function test() {
                         a = 0;
                         alert(a); 
                         alert(this.a);
                         var a;
                         alert(a);
                     }
             test(); //  0   5   0
             new test(); //  0   undefined   0  
             // new 一下就会出现3部内部转换
  
             //   1.var this = Object.create(test.prototype)
             //   2.然后添加上this的属性
             //   3.return this

             // Object.create(test.prototype)上没有a所以 打印undefined

包装类

原始值跟引用值的储存空间不同,原始值储存在栈内存中,不能有属性和方法,在调用属性时,

他会隐式的发生一个过程 new一个Number,随后立即 删除.

       var str = "abc";

            // new String('abc').length;      delete
        //原始值没有属性方法,当调用他的方法时,内部会产生包装类
        //使得str = "abc",会在内部转化成 对象字符串方法new String("arc");
        //所以可以访问到length属性;

        console.log(str.length)

判断字符串字节长度

    var str = "abcd李白";

    //1.把字符串长度全部按小于255字节算,然后查询到每有一个大于255的,就加一
    function strLength(str) {
        var count = str.length;
        for(var i = 0; i < str.length; i ++) {
            if(str.charCodeAt(i) > 255) {
                count ++;
            }
        }
        return count;
    }

    //2.创建一个空容器,然后判断每个字符串字节,小于255 加1,大于255 加2
    function strLength(str) {
        var count = 0;
        for(var i = 0; i < str.length; i ++) {
            if(str.charCodeAt(i) > 255){
                count += 2;
            }else{
                count ++;
            }
        }
        return count;
    }

call--apply

  call apply
不同点

需要把实参按照形参的个数传进去

需要传一个arguments 数组

相同点 改变this指向 改变this指向

圣杯模式

var inherit = (function () {
    var F = function(){};
    return funtion(Target,Origin){
        F.prototype = Origin.prototype;
        Target.prototype = new F();
        Target.prototype.constructor = Target;
        Target.prototype.uber = Origin.prototype;
    }
}());

for   in 循环

遍历 枚举 对象用的,for in  循环,因为不知道对象的length所以用for in

如果是手动设置的原型上的值都可以打印,系统自带的不能打印

遍历属性想获取对象里面的值要写成方括号形式obj[prop];

如果不想获取到原型上的属性要使用hasOwnproperty方法

in 操作符,是能不能再对象上调用这个属性,原型上的也算。

var obj = {
    name : "li",
    age : "123",
    sex : "male",
    height : 123,
    __proto__ : {
        lastName : "bai"
    }
}

for(var prop in obj) {
    if(obj.hasOwnproperty(prop)) {//不获取原型上的属性
        console.log(obj[prop]);
    }
}

instanceof操作符

A instanceof B

看A对象的原型链上有没有B的原型

var person = new Person();
person instanceof Person

区别数组和对象的方法{}[]

var arr = [];

var obj = {};

1.用 constructor

[].constructor   会输出 function Array(){[native code]}

obj.constructor   会输出  function Object(){[native code]}

2.用  instanceof

[] instanceof Array   会输出 true

obj instanceof Array   会输出 false

3.用 call toString  (各种构造函数都重写了 toString方法)   用这个好

Object.prototype.toString.call([]);    输出 array

Object.prototype.toString.call({});    输出 object

Object.prototype.toString.call(123);    输出  number;

typeof 返回值

特殊:空值传到typeof里 会返回 undefined , null  会返回 object ,  undefined 会返回 undefined , [] {} 会返回object , 

Array , Object 会返回 function

正常返回 :

number   string    boolean   object     undefined      function  

普通克隆模式

针对于没有引用值的克隆

var obj = {
    name : "abc",
    age : 12,
    sex : "male",
    card : ["visa","un"]
}
var obj1 = {};

function kelong(origin,target) {
    var target = target || {};
    for(var prop in origin){
        if(origin.hasOwnproperty(prop)){
            target[prop] = origin[prop]
        }
    }
    return target;
}
kelong(obj,obj1);

深层克隆模式

 遍历对象 for(var prop in obj)

 1.判断是不是原始值 typeof() object

 2.判断是数组还是对象 instanceof constructor toString

 3.建立了相应的数组或对象

 4.递归

var obj = {
    name : "abc",
    age : 12,
    sex : "male",
    car : {
        num :"123",
        qwe :{
            er : "df",
            ter : "dssd"
        }
    }
}

function deepClone(origin,target) {
    var target = target || {},
        toStr = Object.prototype.toString,
        arrStr = "[object Array]";
    for(var prop in origin) {
        if(origin.hasOwnproperty(prop)){
            if(origin[prop] !== "null" && typeof(origin[prop]) == 'object') {
                target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {};
                deepClone(origin[prop],target[prop]);
            }else{
                target[prop] = origin[prop];
            }
        }
    }
    return target;
}
deepClone();

数组

var arr = [];    数组自变量 优先使用 var arr = new Array();
传的参数是数组内的内容 传的参数表示数组的长度

改变数组的几种方法

push , pop , shift , unshift , sort , reverse , splice

不改变原数组

concat , join , split , toString , slice

push方法原理

var arr = [1,2,3];
Array.prototype.push = function () {
    for(var i = 0; i < arguments.length; i ++) {
        this[this.length] = arguments[i];
    }
    return this.length;
}

给数组升序,降序

var arr = [10,2,9,13,4,8,9];
arr.sort(function(a,b){
    return a - b; //升序
    return b - a; //降序
})

给一个有序数组乱序

var arr = [1,2,3,4,5,6];
arr.sort(function(){
    return Math.random() - 0.5;
})

类数组

属性要为索引(数字)属性,必须有length属性,最好加上push

类数组赋值例子:

var obj = {
    "2" : 'b',
    "3" : 'c',
    "length" : 2,
    "push" : Array.prototype.push
}

obj.push('a');
obj.push('d');

//push 内部原理是根据length改变的
// 先把长度赋值,然后长度++

Array.prototype.push = function (target) [
    obj[obj.length] = target;
    obj.length ++;
}

封装type方法

function type(target) {
    var template = {
        "[object Array]" : "array",
        "[object Object]" : "object",
        "[object Number]" : "number - object",
        "[object Boolean]" : "boolean - object",
        "[object String]" : "string - object"
    };
    if(target == null) {
        return "null";
    }
    if(typeof(target) == 'object') {
        var str = Object.prototype.toString.call(target);
        return template[str];
    }else{
        return typeof(target);
    }
}

// 先判断是否是 null类型 
// 判断是不是object对象类型,如果是 在用toString.call()方法判断引用值,然后输出
// 剩下的原始值直接typeof判断

原型链上数组去重

var arr = [1,2,1,2,3,3,5,5,4,2,1,6,2,6,5];

Array.prototype.unique = function () {
    var temp = {},    //接收数组内容
        arr = [],    //要返回的新数组
        len = this.length;
    for(var i = 0; i < len; i ++) {
        if(!temp[this[i]]){    //取类数组没有赋值的位
            temp[this[i]] = 'abc';
            arr.push(this[i]);
        }
    }
    return arr;
}

在数组中取出重复的数

原理:

将传入的数组arr中的每一个元素value当作另外一个新数组b的key, 然后遍历arr去访问b[value],

若b[value] 不存在, 则将b[value] 设置为1, 若b[value] 存在, 则将其加1。 可以想象,

若arr中数组没有重复的元素, 则b数组中所有元素均为1; 若arr数组中存在重复的元素, 则在第二次访问该b[value] 时, b[value] 会加1, 其值就为2了。 最后遍历b数组, 将其值大于1的元素的key存入另一个数组a中, 就得到了arr中重复的元素。

var arr = [1,2,3,4,5,6,7,8,9,1,2,1,1,5,4,45,45,5,5,45,10];

function duplicates(arr){
//声明两个数组,a数组用来存放结果,b数组用来存放arr中每个元素的个数
    var a = [],
        b = [];
//遍历arr,如果以arr中元素为下标的的b元素已存在,则该b元素加1,否则设置为1
    for(var i = 0; i < arr.length; i ++) {
        if(!b[arr[i]]){
            b[arr[i]] = 1;
            continue;
        }
        b[arr[i]] ++;
    }
//遍历b数组,将其中元素值大于1的元素下标存入a数组中
    for(var i = 0; i < b.length; i ++){
        if(b[i] > 1){
            a.push(i);
        }
    }
    return a;
}

try......catch  防错

try{
    console.log('a');
    console.log(b);        //如果遇到出错,不会往下执行try里的语句
    console.log('c');
}catch(e){
    console.log(e.name + " : " + e.message);//会把错误报出来
}

猜你喜欢

转载自blog.csdn.net/jiayuan237513457/article/details/82109346