1、typeof類型

(function () {
    return typeof arguments; 
})();

//argument实参集合,即对像,有数组的长度,也可for,但没有arr的方法;push unshift

var f = function g() {
    return 23;
}
typeof g();

//有名函数表达式,不规范,不建议写,g()找不到的,在外部typeof 找不到的g(),其实是error


(function (x) {
    delete x; 
    return x;
})(1)

//删除元素,不能删除变量也不能删除参数,只能删除一个对像下面的方法,所以删不掉,返回的还是1

var y = 1, x = y = typeof x;
x;

//从右往左运算; typeof 没有值,返回undefined; 注意;type返回字符串类型  所以是加了双引号的 "undefined"

(function f(f) {
    return typeof f(); 
})(function () {
    return 1;
}) 

//執行后返回1 typeof == 'number'


var foo = {
    bar: function () {
        return this.baz
    },  
    baz: 1
};

//this指向哪?this不看在哪定义,关键看在哪执行;


(function () {
    return typeof arguments[0]();
})(foo.bar);  

// 正常来写,this肯定指向foo 但当一个整体当参数传进来时,this使用window调用,window下没有.baz,所以返回 'undefined'


var foo = {
    bar: function () {
        return this.baz
    }, 
    baz: 1
};
typeof (f = foo.bar)()


//this指向哪? this不看在哪定义,关键看在哪执行;还是指向window,所以是 'undefined'

var f = (function f() {
    return '1'
}, function g() {
    return 2;
})()
typeof  f;

//分组选择,变量执行最后一位 var a = (1,2,3), alert(a)  3

var x = 1;
if (function f() {}) {
    x += typeof f;
}
x;

//函数声明,写法是不允许的  ;写进去后名字f找不到了;肯定是返回 'undefined',但if是否会执行?
//但fn写在if里,确实返回真,所以会执行;1 + 'undefined' == '1undefined'


var x = [typeof  x, typeof y][1];
typeof typeof x;

//x不需要看,没意义 ;
// 不管x = 什么,返回必然是字符串,typeof 字符串返回 string

(function (foo) {
    return typeof foo.bar; 
})({foo: {bar: 1}});


//整体下面只有一个foo,没有bar相當於:  {foo:{bar:1}}).bar  所以是undefined


(function f() {
    function f() {return 1}
    return f();   //函數聲明會預解析,所以當到這裏時,f()覆蓋,已經是2
    function f() {
        return 2
    }
})()


function f() {
    return f;           //本來是對的,但如果 return回同行函數,則會覆蓋,所以是false
}
new f() instanceof f;   //instanceof前面是不是構造fn出來的,如果是返回true;  new f() 執行完後其實是f,即 f instanceof f  == false;


width(function (x, undefined) {
}).length;   //函數的開度就是函數的形參; argument是實參集合


2、作用域
1)外層的變量內層可以找到,全局;內層的變量外層找不到,局布;

    var a = 10 ;
    function aaa(){
        alert(a)
    }
    function bbb(){
        var a = 20
        aaa();  //這裏調用時並不是把aaa()函數拿進來,而是在外部找aaa()函數,所以是10
    }
    bbb();
 function aaa(){
        a = 10;  //相當於在外面定義,所以可找a ,當 var 不加時全自動生成全局變量,(不建議使用;把有變量都定義為var
    }
    aaa()
    alert(a)
function aaa(){
    var a = b = 10;  //這種寫法相當於 var a = 10; b= 10,即b不使用var聲明,所以b是全局;
}
aaa()
// alert(a);
alert(b);
    var a = 10;
    function aaa(){
        alert(a);   //undefined 第二步預解析時,有var,所以a = undefined; 之後a 在aaa()裏執行了,相當於aaa()類似於一個window的作用域那樣理解,裏面有var a了,所以a不會向外面找;
       var  a = 20
    }
    aaa()

3)、變量的查找;就近原則去尋找var 定義的變量;

    var a = 10;
    function aaa(){
        alert(a);  //10
        a = 20
    }
    aaa()

    var a = 10;
    function aaa(){
        a = 20
        alert(a);  //20
    }
    aaa()

    var a = 10;
    function aaa(){
        alert(a);
        var a = 20
    }
    aaa()

    /*   alert(a);
         var a = 20
    * =========== 相等於
    * var a;
    * alert(a);
    * a = 20;
    * 所以是undefined;
    *
    */ 

    var a = 10;
    function aaa(){
        bbb()
        alert(a);
      function bbb(){
          var a = 20;
      }
    }
    aaa()  //10 aaa()裏的a找不到bbb()裏面的a 

4)、當參數跟局布變量重名時,優先級等同

    var a = 10;
    function aaa(a){
        alert(a);
        var a = 20;
    }
    aaa(a)  //10

    var a = 5;
    var b = a;
    b += 3;
    console.log(a);  //普通變量不會影響到a,所以是5*/

    //對像是引用關係 ;
    var a = [1,2,3]
    var b = a;
    b.push(4)
    console.log(a); //[1, 2, 3, 4]

    var a = 10;
    function aaa(a){
        a += 3; //a重新給地址了;
    }
    aaa(a)
    alert(a); 
//10,當傳參數進後來後相當於重新賦值;因為a是基本類型,不是對象數組,所以裏面的改變不會影響 到a,參數跟局布變量概念一樣;


    var a = [1,2,3];
    function aaa(a){
        a.push(4); //a是引用關係了,地址沒變;
    }
    aaa(a)
    alert(a);//[1,2,3,4]
/**********************************************************************/
    var a = [1,2,3];
    function aaa(a){
        a = [1,2,3,4]; //修改了,所以不變的。在內存中重新生成;
    }
    aaa(a)
    alert(a); //[1,2,3]

3、題形
寫一個字符串轉成駝鋒的方法;
解一:

var str = 'border-bottom-color'
function text(str) {
    var arr = str.split('-');
    for (var i = 1; i < arr.length; i++) {
        arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
    }
    return arr.join('');
}
console.log(text(str));

解二:

var str = 'border-bottom-color'

function textZ(str){
/*找-字符  再用g全局匹配;*/
    var re = /-(\w)/g; 
    return str.replace(re, function (_0,_1) { 
/* 第一個整體,第二個代表子項 */
        return _1.toUpperCase();    /*
        注意:這裏 _0 ==  _B  _C
                _1 == B C
        */
    })
}
console.log(textZ(str));

查找字符串中出現最多的字符及個數;
解一:

var str2 = 'asdlkfjasldkfjalksdjfkllkdkkaksldfkkkkkk'
function textC(){
    /*通過json存*/
    var obj = {}
    var num = 0;
    var value = '';
    /*思路:
    * obj = {
    * a:[],
    * b:[],
    * c:[]
    * }
     */
    for (var i = 0; i < str2.length; i++) {
        if ( !obj[ str2[i] ] ) {  //當不存在時,即去掉重複添加;
            obj[ str2[i] ] = [];  //先創建空數組集合;
        }
        obj[ str2[i] ].push(str2[i]); //再把每一項push進創建的每個集合裏;
    }
    /*對比集合裏的項數;
     * */
    for (var attr in obj) {
        if (num < obj[attr].length) {
            /*這兩步只是num<obj[attr].length才會走這裏*/
            num = obj[attr].length
            /* num永遠是集合中最長的,理解下這裏*/
            value = obj[attr][0];
        }
    }
    return '最多是' + value + '一共有' + num + '個'
}

console.log(textC(str2));

解二:

var str3 = 'asdlkfjasldkfjalksdjfkllkdkkaksldfkkkkkk'

function testCZ(str3){
    var arr3 = str3.split('');
    arr3.sort();
    str3 = arr3.join(''); //把相同的排在一起;再存
    console.log('abc'+str3);
    var re = /(\w)\1+/g;  /* \1代表著跟第一個子項完全一樣的,即複製多個才匹配到,注意理解; + 表示可以出現多次,g表示多次匹配 */
    var num3= 0; var value3 = 0;

    str3.replace(re, function (_0,_1) {
        if(num3<_0.length){
            num3 = _0.length;
            value3 = _1;
        }
    })
    return '最多是' + value3 + '一共有' + num3 + '個'
}
console.log(testCZ(str3));

如何給字符串加千分符

解一:

var str4 = '12658656489' //[12,658,956,564,689]
function test4(str4) {
    var inum = str4.length % 3;
    var prev = '';
    var arr = [];
    var inow = 0; //三位三位計算
    var tmp = ''
    if (inum != 0) {
        prev = str4.substring(0, inum);
        arr.push(prev)
    }
    str4 = str4.substring(inum)
    for (var i = 0; i < str4.length; i++) {
        inow++
        tmp += str4[i]
        if (inow == 3 && tmp) {
            arr.push(tmp);
            tmp = '';
            inow = 0;
        }
    }
    return arr.join(',')
}
console.log(test4(str4));

解二:


var str5 = '126556489'
function testZ4(){
    /*後面必須是三位數字*/
    var re = /(?=(?!\b)(\d{3})+$)/g;
    /*
    * 寫一個前期聲明:(?=)
    * 子項裏是數字(?=(\d))
    * 聲明是3位 (?=(\d{3}))
    * 3位最少出現1次,所以(?=(\d{3}+))
    * 然後位置出現在後面結束位置(?=(\d{3}+$))
    * 然後是全局:/(?=(\d{3})+$)/g  bug:如果剛好是3位3位,則起始位置也會匹配到;
    * 所以前項聲明前再來一個反前期聲明:/(?=(?!\b)(\d{3})+$)/g
    * \b代表正則中的獨立部分;比如:開始,結束,空格,都是獨立部分,所以,不包超始位置加\b
    * */
    return str5.replace(re,',')
}
console.log(testZ4(str5));

前項聲明入 反前項聲明

    (function () {
        var s =  'abacad'
        var re = /a(?=b)/g;    //匹配 ab,但只替換匹配到的ab中的a,b不替換;
        s =  s.replace(re,'*')
        console.log(s);  //*bacad

    })();
    (function () {

        var s =  'abacad'
        var re = /a(?!b)/g;    //匹配 ab,a後面不能匹配到b,其他可以匹配
        s =  s.replace(re,'*')
        console.log(s);  //ab*c*d
    })()

把一個字符串中所有數字類型以數組存形輸出;

解一:

var str6 = 'js123kdslfkjd78klw0jfldjs966gg989dfsdf5'
function text6(str6) {
    var arr = []
    var tmp = ''
    for (var i = 0; i < str6.length; i++) {
        if (Number(str6[i]) || str6[i] == 0) {
            tmp += str6[i]
        }
        else {
            if (tmp) {
                arr.push(tmp);
            }
            tmp = ''
        }
    }
    arr.push(tmp) //修復最後一位是數字的情況;
    return arr
}
console.log(text6(str6));

解二:

    var str7 = 'js123kdslfkjd78klw0jfldjs966gg989dfsdf5'

    function test7(str7){
        var arr = []
        str7 = str7.replace(/\d+/g, function (_0,_1) {
                return arr.push(_0)
        })
        return arr;
    }
    console.log(test7(str7));

4、限制條件題 ;
ab兩變量,不用第3個變量來切換兩個變量值;
只適用數字:

    var a = 5;
    var b = 6;
    a = a + b
    b = a - b
    a = a - b;
    console.log(a); //6
    console.log(b); //5

適用所有類型:

 var a = 'hello'
 var b = 'hi'

 a = [a,b]
 b=a[0] //順序不能換;
 a=a[1]
 console.log(a);
 console.log(b);

有一個數n=5,不用循環,怎麼返回[1,2,3,4,5]這樣一個數組;
利用遞歸

    var n = 5
    function arrshow(n){
        var arr = []
        return (function k() {
            arr.unshift(n)
            n--;
            if(n!=0){
    //可直接使用下面,調用當前正被執行的對象,即()()裏的對象,所以不需要命名;
              //  arguments.callee() 
                k() //也可使用遞歸,但需要命名函數本身,即加k
            }
            return arr;
        })()
    }
    console.log(arrshow(5));

利用replace


    var n = 5;
    function arrshow(n){
        var arr = [];
        arr.length = n+1; //[,,,,,]
        var str = arr.join('a') //str = 'aaaaa'

        var arr2 = []
        str.replace(/a/g, function () {
            arr2.unshift(n--)
        })
        return arr2
    }
    console.log(arrshow(5));

一個數n,當小於100返回n,否則返回100
n解:

    var n = 50;
    function shown(n){
       return n < 100 ? n : 100;
    }
    console.log(shown(n));

/***********************************/
    var n = 50;
    function shown(n){
       return Math.min(n,100)
    }
    console.log(shown(n));

/***********************************/
    var n = 50;
    function shown(n){
       var arr = [n,100];
        arr.sort(function (n1,n2) {
            return n1 - n2
        })
        return arr[0]
    }
    console.log(shown(n));

/***********************************/
    var n = 500;
    function shown(n){
        var m = ''+n
        for(var i=2;i< m.length && n>0 ;i++){  //位數來判斷;
            return 100
        }
        return n;
    }
    console.log(shown(n));
/***********************************/
    var n = -500;
    function shown(n){
        var json = {name:'hello'}
        var m = n<100 || json;

        for(var attr in m){
            return 100
        }
        return n;
    }
    console.log(shown(n));

/***********************************/
    var n = 500;
    function shown(n){
        var m = n>=100 && 100
        return m = m || n;
    }
    console.log(shown(n));



<h2>算法</h2>
斐波那契数列:前兩位相加等於第三位

遞歸:

function aaa(n){
    if(n<=2){
        return 1
    }
    return aaa(n - 1) + aaa(n - 2)
}
console.log(aaa(8)); //21

迭代:(開循環操作)

function bbb(n){
    var num1 = 1; //第1
    var num2 = 1; //第2
    var num3 = 0;
    for(var i=0;i<n-2;i++){
        num3 = num1 + num2;
        num1 = num2 //num1變後一個數
        num2 = num3 //上一次num3的值
    }
    return num3;
}
console.log(bbb(8));

<h2>數組排序</h2>

快速排序

function qsort(arr){
    if(arr.length<=1){
        return arr;
    }
    var n = Math.floor(arr.length/2)
    var nV = arr.splice(n,1)
    var l = []
    var r = []
    for(var i=0;i<arr.length;i++){
        if(arr[i]<nV){
            l.push(arr[i]);
        }
        else{
            r.push(arr[i])
        }
    }
    return qsort(l).concat([nV],ccc(r))
}
alert(qsort([4, 5, 6, 3, 2, 10]))

冒泡排序


兩兩比較;嵌套2次循環

function msort(arr) {
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < arr.length - i; j++) {//每兩次,當第一輪找到一個數時,可去掉已找到的,即減i
            toCon(i, i + 1)
        }
    }
    function toCon(prev, next) {
        var tmp = ''
        if (arr[prev] > arr[next]) {
            tmp = arr[prev]
            arr[prev] = arr[next]
            arr[next] = tmp;
        }
    }
    return arr
}
console.log(msort([40, 5, 6, 3, 2, 10]));

简单选择排序:每一次找最小值,把最小值放在最前面;

function ssort(arr) {
    if (arr.length == 1) {
        return arr;
    }
    var iMin = arr[0]
    var iIndex = 0;
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] < iMin) {
            iMin = arr[i]
            iIndex = i; //最小值的下标
        }
    }
    var prev = arr.splice(iIndex, 1);//每次把最小值剪切到第1位
    return prev.concat(ssort(arr))
}
console.log(ssort([40, 5, 6, 3, 20, 10]));

<h2>数组去重</h2>
1

function dup(arr) {
    var result =[ arr[0] ] ; //初始化给第一项,注意放在数组里
    for (var i = 1; i < arr.length; i++) { //从第1个开始
        if (toCon(arr[i])) { //封方法,返回真表示无重复
            result.push(arr[i])
        }
    }
    function toCon(v) {
        for (var i = 0; i < result.length; i++) {
            if (result[i] == v) {
                return false
            }
        }
        return true //不走if返回ture,上面可添加
    }

    return result
}
console.log(dup([32, 3, 4, 34, 5, 44, 3]));

2、利用obj属性

function jdup(arr) {
    var result = []
    var obj = {}
    for (var i = 1; i < arr.length; i++) {
        if (!obj[arr[i]]) {
            result.push(arr[i])
            obj[arr[i]] = 1; //让obj的32:1,所以obj = {32:1,3:1,4:1....}
        }
    }
    return result
}
console.log(jdup([32, 3, 4, 34, 5, 44, 3, 55, 32]));