js相关笔记(八)

1.对象字面量,字面量是指表面上的值,对象字面量默认是{},所以对象也可以是用{}来创建并且来添加属性和方法,如:
◆var student={name:"flag",age:20,sayHi:function(){}};
◆var student={"name":"flag","age":20,"sayHi":function(){}};
◆这种方式类似于var student=new  Object();然后给student添加属性及方法,但是比直接new Object要更加的方便,但是也没有模拟定义类型然后通过new关键字配合构造函数来创建对象灵活,只不过这么做很方便。


2.JSON就是javascript对象,也是对象字面量的一种表现形式,对面字面量有两种表现形式,一种是var student={name:"flag",age:20,sayHi:function(){}},里面的key不是字符串,另一种是var student={"name":"flag","age":20,"sayHi":function(){}},里面的key是字符串,而JSON就是第二种对象字面量的表现形式;。


3.在javascript中对象中的每一个属性可以通过遍历的方式取值,数组是通过索引来遍历取值的,因为数组有length,而对象只能通过遍历key来取value,对象没有length。


3.数组遍历可直接是for循环也能使用for..in遍历键值对,数组的索引就是数组元素的key,而对象遍历只能使用for..in,除非你对象中的成员是和数组一样用索引下标作为key,那么也能使用for循环来遍历,但是一般不会去那样做,因为没有多大意义。


4.推荐学习网站:https://www.w3ctech.com/


5.ecma6标准学习:http://es6.ruanyifeng.com/


6.值类型在栈中开辟的空间存的是值,引用类型在栈用开辟的空间存的是在堆中开辟的空间的地址
★在函数的参数中传递值类型的变量如同是在传值,如果你在函数中修改那个值对原来的值类型变量没有影响,因为你只是把实际参数中的值传递给了形式参数,形式参数会在栈中另外开辟一个块儿空间存取这个值,在函数中的操作实际是对形参进行操作,所以如果是值类型那么就是对形参在栈中的值进行修改,如果是引用类型那么就是对形参在栈中对应的地址所指向的堆中的数据进行操作,实际参数在栈中的地址与形式参数在栈中的地址一模一样,他们都是指向同一块儿堆中的内存空间,改的也是同一个空间中的数据。


7.操作一门语言其实就是操作它的内置对象和它的基本语法,内置对象其实就是已经写好定义好的对象,你创建出来直接用就可以了,但是当内置对象很庞大的时候,由于不是你自己写的也不是你自己定义的,所以就会出现排错时容易出问题。


8.javascript中的内置对象
◆有 Date Array Math RegExp String Number Error...
◆学习javascript内置对象,主要学习的是API(一些功能方法),Html5的方法
◆学习API主要清除几点
◇调用者:谁调用的 如parseInt和toString,parseInt没有调用者,直接传参数即可,如parseInt(xx);,而toString有调用者,如xx.toString();,然后可传可不传参数
◇参数:有或者无 有几个
◇返回值:有或者无,什么类型的
◇功能:干什么用的


9.自学的方法
◆离线:看一些离线手册 (不是很全)
◆在线:看W3C官方文档 以及一些其它社区的网站,如MDN的官网(开发者网站):   https://developer.mozilla.org/zh-CN/(很好)等等


10.数组定义的方式有两种
◆第一种 var arr=new Array();,使用这种方式定义需要注意,如果Array()构造方法中传递一个参数并且还是数字,那么就是创建对象的同时定义了这个数组的初始长度,如果传递多个参数,那么就是创建对象的同时初始化数组,按照顺序给数组的元素赋值,索引下标从0开始;
◆第二种 var arr=[];这个是数组字面量的定义方式,[]是数组字面量值,var arr=[1,2,3,5,4,6,2];表示定义了一个数组并且初始化了那么多的值,索引下标也是从0开始的。


11.检测一个变量是否是一个对象的实例,使用instanceof,复杂数据类型用字面量方式定义出来或new+构造函数的方式创建出来也都能够检测出来,简单数据类型只能够用new+构造函数的方式创建出来才能进行检测,但是那已经不是简单数据类型了而是一个对象实例,只要不是对象的实例必为false,依据如下
◆[] instanceof Array//true。
◆new Array() instanceof Array//true。
◆"123" instanceof Array//false。
◆2 instanceof Number//false。
◆new Number(2) instanceof Number//true.
★也可以用来判断 自己模拟定义的类型,如 【     //定义了一个构造函数  
function Student(){}
//创建一个对象
var stu=new Student();
//检测是否是这个对象的实例
console.log(stu instanceof Student);//true
//其实模拟的对象其实也还是Object对象的实例,但是先是模拟的Student对象的实例再是Object对象的实例
console.log(stu instanceof Object);//true

★所有通过new出来的对象实例,其实间接都是Object对象的实例,但是先是它自己的new关键字后面跟的那个对象的实例,如果 var arr=new Array(),它显示arr显示Array对象的实例,然后再是Object对象的实例。


12.如果要拼接字符串,可以先将每一个字符串存到数组中去,然后使用join方法来返回完整的字符串,这种方法不容易发生内存泄漏,因为字符串是特殊的引用类型,使用变量存取字符串并不是存在栈中而是存在堆中,栈中存的是当前字符串的哈希码,这个哈希码对应堆中的一块空间,那个空间存的才是字符串,然后每一次拼接字符串都是在不断改变这个变量存取在栈中的哈希码,于是就会不断的在堆中开辟空间存取新的拼接后的字符串,这样下去就会导致内存泄漏,而数组的join方法就不一样,数组中的字符串则会按照规律存取,倒是后调用join方式时也按照规律拼接,这样就不会出现不断的开辟新空间存取拼接后新的字符串了。


13.函数内部的arguments关键字,是调用函数时实际传递的参数的数组,也就是每一个传递进去的参数都会存到这个argumnets数组中去,但是这个数组是一个伪数组,使用instanceof关键字检测是否是Array对象的实例时返回值为false,并且这个伪数组长度还是固定的,你传几个参数进去,伪数组的长度就是多少,伪数组自带的方法没有真数组的多。
◆获取函数实际的参数个数可以在函数内部使用 arguments.length,获取函数形式的参数个数可以使用 函数名.length。
★arguments.callee()可以调用当前函数,类似于 函数名(),而且console.log(函数名);等价于console.log(arguments.callee);只不过一个arguments是每一个函数内部的,不能直接在外部访问


14.数组的栈和堆特性
◆进栈 push() 可以一次性放多个参数,内部是使用 遍历argument伪数组来存的,使用push方法是将数据存数组的最末项,存进去之后会返回当前数组的长度,出栈pop() 可以从数组的最末尾取出一个数组元素并且返回,但是也会把这个数组元素移除原数组。
◆进队列 unshift() 可以一次性放多个参数,是将元素存到数组的最前面,存进去之后会返回数组的长度,出队列shift()可以从数组的最前面的元素返回,但是也会把这个取出来的数组元素移除原数组。


15.数组的reverse(),内部使用的是for循环遍历前后项数组元素交换,对原数组有影响。


16.数组的sort(),内部默认使用的排序方法是首字母的unicode码,也就是比较ascll码表中的ascll码,你可以通过传递规则或者行为来改变排序规则,其实就是传递一个回调函数,如【
arr7.sort(function (a, b) {
            return a- b;//返回两个数相减的值,如果是a-b则是从小到大的升序,反之b-a为从大到小的降序      
 })
】,sort方法内部使用的还是冒泡排序【
        //sort 方法中设置规则的原理是 冒泡排序
        var array=[];
        function bubbleSort(fn){ //
            //外循环控制轮数
            for(var i=0;i<array.length-1;i++){
                //开闭思想
                var flag=true;
                //内循环控制次数
                for(var j=0;i<array.length-1-i;j++){
                    //判断的时候调用规则
                    if(fn(array[j],array[j+1])>0){
                        var temp=array[j];
                        array[j]=array[j+1];
                        array[j+1]=temp;
                    }
                      //上面的等价于下面的
//                    if(array[j] - array[j+1] > 0){
//                        var temp=array[j];
//                        array[j]=array[j+1];
//                        array[j+1]=temp;
//                    }
                }
            }
        }



17.字符串的charCodeAt()方法可以返回这个字符串首字符的ascll码,"a".charCodeAt()//97


18.数组的常用API(功能方法)
◆连接与划分截取和剪切替换
◇数组的连接使用的是concat方法,原来的数组不会受影响,var newArr=arr.concat(arr2);返回值是一个新的数组。
◇数组的截取(划分)使用的是slice方法,原来的数组不会受影响,var newArr=arr.slice(2,4);//方法的第一个参数是表示起始索引,第二个参数表示结束索引,内部使用的是for循环,var i=2;i<4,所以是包含左边括号的数字的但并不会包含右边括号的数字,如果方法只传递一个参数的话,那么第二个参数值默认为数组的length-1,如果参数的值为负数,那么会在方法内部进行转换,转换的方式为数组的length+参数值(参数值为负),注意点是如果第一个参数大于第二个参数那么就会返回空数组,因为内部使用的是for循环,如i=4,i<2,那么就不会进入循环体。
◇数组的剪切替换(剪接)使用的是splice方法,原来的数组会受到影响,因为是剪切原来的数组返回新的数组,var newArr=arr.splice(2,4);////方法的第一个参数是表示起始索引,第二个参数表示 剪切的长度,如果剪切的长度大于数组的长度,那默认从起始索引截取到末尾,如果剪切的长度为负数,那么默认一个也不截取返回一个空数组,如果其实索引为负数,那么默认值为数组length+第一个参数(参数字为负),var newArr=arr.splice(2,4,"吕布","赵云","关羽");除了前两个参数外,后面无论多少的参数值都表示在原来的数组被剪切的位置插入这些参数值。
◆从前或者从后获取数组元素索引
◇数组的indexOf方法是根据数组元素 找该数组元素的索引下标,  从前往后找  ,找不到就会返回 -1,arr.indexOf("a")。
◇数组的lastIndexOf方法是根据数组元素 找该数组元素的索引下标,  从后往前找  ,找不到就会返回 -1,arr.lastIndexOf("a")。
◆所有的遍历方法
◇数组的 every()方法 用于 循环检查这个数组中的值是否全部符合规则  只要有一次返回false 就终止检测  返回false 不合格【
        var arr=[1,2,5,1,2,5,3,6,21];
        var flag=arr.every(function(element,index,array){
            if(element>6){
                console.warn(element+"大于6");
                return false;
            }
            return true;
        });
        console.log(flag);//false

◇数组的filter()方法 用于 循环筛选这个数组中的值是否符合规则  会将返回为true的数组元素放入一个新的数组中去 而返回为false的数组元素则不会放入新的数组中去 【
var newArr=arr.filter(function(element,index,array){
            if(element>6){
                return false;
            }
            return true;
        });
        console.log(arr);//[1, 2, 5, 1, 2, 5, 3, 6, 21]
        console.log(newArr);//[1, 2, 5, 1, 2, 5, 3, 6]

◇数组的forEach()方法 用于循环遍历数组中每一个元素,没有任何返回值 默认返回undefined【
var str="";
        var flag=arr.forEach(function(element,index,array){
            str+=element;
        });
        console.log(str);//1251253621
        console.log(flag);//undefined

◇数组的map()方法 用于循环遍历修改数组中每一个元素的值 并且会返回修改后的数组【var arr2=["吕布","貂蝉","关羽","赤兔"];
        var newArr2=arr2.map(function(element,index,array){
            return element+"你好";
        });
        console.log(arr2);//["吕布", "貂蝉", "关羽", "赤兔"]
        console.log(newArr2);//["吕布你好", "貂蝉你好", "关羽你好", "赤兔你好"]

◇数组的some()方法 用于循环检查这个数组中的值是否有一个符合规则 只要返回一次true 就会终止检测 返回true  与 every相反 every是全部合格  some只要一个合格【
var flag=arr.some(function(element,index,array){
            if(element>6){
                console.warn(element+"大于6");
                return true;
            }
            return false;
        });
        console.log(flag);//true



19.清空数组
◆arr.splice(0);原数组从前剪切到后,原数组就空了
◆arr.length=0;原数组的长度为0 ,原数组就空了
◆arr=[]或者arr=new Array();原数组重新被赋值,原数组就空了


20.清除数组中的重复项
◆使用数组的forEach方法 配合 新数组的some方法【
    arr.forEach(function(element,index,array){
        if(
               ! newArr.some(function (element2,index2,array2) {
            if(element2==element){
                return true;
            }
            return false;
        })
        )
        {
            newArr[newArr.length]=element;
        }
    });

◆使用数组的forEach方法 配合 新数组的indexOf和lastIndexOf方法【
arr.forEach(function(element,index,array){
    if(   ! (newArr.indexOf(element) !== -1 &&
            newArr.indexOf(element) === newArr.lastIndexOf(element)
            )
      ){
        newArr[newArr.length]=element;
    }
});

◆使用for循环派和 当前数组的indexOf和lastIndexOf方法【
for(var i=0;i<arr.length;i++){
        if(
                arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])//前后同一个元素索引不一样
        ){
            arr.splice(i,1);//剪切掉前面的元素,保留后面的元素
            i--;
        }
    }



21.构造函数的原理
◆如原始的Number对象  
【var num=new Number("222");
    console.log(num);//[[PrimitiveValue]]: 222


    var number=Number("222");//222
    console.log(number);】


◆自己模拟的Numbers对象,只是给当前对象添加了一个[[PrimitiveValue]]这样一个原始值的成员并且赋值了,然后再返回这样的一个隐式转后的值,所以使用方法来进行字符串转换为数值就是这样的【
    var num1=new Numbers("222");
    console.log(num1);//[[PrimitiveValue]]: 222
    var number1=Numbers("222");
    console.log(number1);//222
    function Numbers(num){
        //给这个成员赋值
        this["[[PrimitiveValue]]"]=num/1;
       //返回 值
        return num/1;
    }
posted @ 2018-06-10 18:05  我叫贾文利  阅读(122)  评论(0编辑  收藏  举报