js 数组、对象、函数等

一、数组

1.数组的创建

1.1 使用字面量创建数组

var arr = [1, 2, 3];

1.2 使用Array创建

没有参数时,空数组
参数只有一个且为数字,则创建的是num长度的数组
参数只有一个但不是数字,则将参数放入数组中作为元素。
多个参数,放入数组中作为元素。

var arr1 = new Array();
var arr2 = new Array(6);
var arr3 = new Array('尔尔er')
var arr4 = new Array(1, 2, 3);

1.3 使用Array.of创建

与Array创建的区别在于参数为1个时,也是作为数组的元素放入 数组

var arr = Array.of(1);[1]
var arr = Array.of(1,2,3);[1,2,3]

2.数组的属性和方法

增删改:

  1. push
    向数组的末尾追加元素,可追加多个
    使用方法:arr.push(增加的元素)
    返回值:追加元素后,数组的长度
    是否改变原数组:改变
		var arr = [1, 2, 3];
        console.log(arr.push(4, 5));
  1. pop
    删除数组的最后一项
    使用方法:arr.pop()
    返回值:被删除的元素
    是否改变原数组:改变
      var arr = [1, 2, 3];
      console.log(arr.pop());
  1. unshift
    向数组的开头添加一个或多个元素
    使用方法:arr.unshift(-1,0)
    返回值:添加后数组的长度
    是否改变原数组:改变
      var arr = [1, 2, 3];
      console.log(arr.unshift(0, -1));
  1. shift
    删除数组的开头项
    使用方法:arr.shift()
    返回值:被删除的元素
    是否改变原数组:改变
      var arr = [1, 2, 3];
      console.log(arr.shift());
  1. splice
    实现数组指定位置的增加、修改、删除
    使用方法:arr.splice(n,m,x)
    返回值:将删除的部分用数组存储起来返回
    是否改变原数组:改变
    增加:①数组末尾增加x项arr.splice(arr.length, 0, x);
    ②数组开始位置增加arr.splice(0,0,x)
      //增加
      var arr1 = ['a','b','c','d'];
      console.log(arr1.splice(4, 0, 'e','f'));
      console.log(arr1.splice(0,0,'g','h'));
      console.log(arr1);

删除:①arr.splice(0) 清空数组
②arr.splice(arr.length-1) 删除最后一项
③arr.splice(0,1) 删除第一项
④删除指定位置arr.splice(要删除位置的索引,要删除的长度)

      var arr1 = ['a','b','c','d','e','f'];
    //   console.log(arr1.splice(0));
      console.log(arr1.splice(arr1.length-1));
      console.log(arr1.splice(0,1));
      console.log(arr1.splice(1,2));

修改:x回替换掉m

      var arr2 = [1, 2, 3];
      console.log(arr2.splice(1,1,200));
      console.log(arr2);

删除数组末尾项的方法:
①delete arr[arr.length-1] 删除后不会改变数组长度
②arr.length–
③arr.pop()
④arr.splice(arr.length–)

向数组末尾追加的方法:
①arr.push(‘要增加的元素’)
②arr[arr.length]=‘要增加的元素’
③arr.splice(arr.length,0,‘要增加的元素’)

查询和拼接

silce

slice(start,end)

用于实现数组的查询,两个参数,从索引start开始,到索引end结束(不包含end,[start,end)), 将查询到的内容以新数组的形式返回。不改变原数组

        var arr = [2, 1, 6, 9, 0];
        console.log(arr.slice(1, 3));

concat

arr.concat(拼接的内容)

实现数组的拼接,可拼接多个,返回值为拼接后的新数组

        var arr1 = [1, 2, 3];
        var arr2 = [4, 5, 6];
        console.log(arr1.concat(arr2));

数组转字符串

toString

将数组转为字符串,没有参数,不改变原数组,转换后的字符串每一项用逗号分隔

var arr = [1,2,3,4];
console.log(arr.toString());

join

将数组转为字符串,参数为指定的分隔符,未指定分隔符则用逗号分隔,指定的分隔符为空字符,则将每项连接起来。

var arr = [1, 2, 3];
console.log(arr.join());//1,2,3
console.log(arr.join(''));//123

检测数组中是否包含某一项

indexOf

检测当前项在数组中第一次出现位置的索引值,返回值为索引值

lastIndexOf

检测当前项在数组中最后一 次出现位置的索引值,返回值为索引值

includes

检测数组中是否包含某项,有则返回true,反之返回false

        var arr = [1, 2, 3, 4, 1];
        console.log(arr.indexOf(1));
        console.log(arr.lastIndexOf(1));
        console.log(arr.includes(1));

排序、排列

reverse

把数组翻转过来,改变原数组

        var arr = [1, 5, 3, 5, 2, 5];
        console.log(arr.reverse());
        console.log(arr);

sort

实现数组的排序,改变原数组

        var arr = [1, 5, 3, 5, 2, 30];
        console.log(arr.sort());
        console.log(arr);

升序

        var num1 = [3,1,20,5,4,6]; 
        function compare(a, b) {
            if (a < b) {
                return -1;
            }else if(a > b) {
                return 1;
            }else{
                return 0;
            }                      
        }
        num1.sort(compare);
        console.log(num1);

降序

        function compare1(a, b) {
            if (a < b) {
                return 1;
            }else if(a > b) {
                return -1;
            }else{
                return 0;
            }                      
        }
        num1.sort(compare1);
        console.log(num1);

find

判断一个变量是否是一个数组

①isArray()判断

②利用变量原型的构造函数是不是Array来判断

var arr = [1,2,3,4];
console.log(Array.isArray(arr))
console.log(arr.__proto__.constructor === Array)

3.数组的遍历

forEach

针对每一个元素执行提供的函数

        var arr = [1, 2, 3, 4, 5];
        arr.forEach(function(item,ind){
            console.log(item);
        });

map

创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来。

        var names = [1, 2, 3, 4, 5, 6, 7];
        // map : 会将函数的返回值组成一个新的数组作为 map的返回值
        var re = names.map(function (item, index, arr) {
            item += 2;
            return item;
        });
        console.log(re);
        console.log(names);

兼容性处理

forEach和map的区别

forEach()方法不会返回执行结果,而是undefined。而map()方法会得到一个新的数组并返回。

4.类数组

类数组具有length属性,类数组没有数组的方法。

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
    </ul>
    let lis = document.querySelectorAll('li');
    console.log(lis);
// lis.push(2);//arr2.push is not a function
console.log(Array.isArray(lis));

类数组转数组:
1)call函数让类数组Array原型的slice方法,截取数组所有项组成一个新数组
2) apply函数修改指向,将空数组和类数组进行连接组成一个新数组
3)使用**Array.from()**可以将类数组转为数组,返回值为一个新的数组
4)…运算符


 	<ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
    </ul>
    
    
        let lis = document.querySelectorAll('li');
        console.log(lis);

        var arr1 = Array.prototype.slice.call(lis);
        arr1.push('我是新增的');
        console.log(arr1);
        var arr2 = Array.prototype.concat.apply([], lis);
        arr2.pop();
        console.log(arr2);
        var arr4 = Array.from(lis);
        arr4.push('hhh');
        console.log(arr4);
        console.log([...lis]);
   

5.二维数组和多维数组

一维数组:arr[]

二维数组:arr[[ ], [ ]]

三维数组: arr[[[ ] ], [ [ ]]]

var arr = [
    [1,11,111],
    [2,22,222],
    [3]
]
console.log(arr[1][2]);
//二维数组的遍历
for (let i = 0; i < arr.length; i++) {
   for (let j = 0; j < arr.length; j++) {
         console.log(arr[i][j]);
   }
}
//用forEach遍历数组
arr.forEach(function(value){
     value.forEach(function(item){
           console.log(item);
     })
})

二、对象

1.对象的创建

字面量创建

var person1 = {
    name: "wu",
    age: 20,
    job: "Software Engineer",
    sayName: function () {
        alert(this.name);
    }
};
console.log(person1);

工厂模式

function createAnimal(name, age, jiao) {
    var o = {}
    o.name = name;
    o.age = age;
    o.jiao = jiao;
    o.sayName = function () {
         alert(this.name);
    }
    return o;
}

var cat = createAnimal("元宝", 2, "maio~~~");
console.log(cat);
var dog = createAnimal("球球", 3, "汪~~~");
console.log(dog.sayName());

构造函数创建

function Animal(name, age, jiao) {
    this.name = name;
    this.age = age;
    this.jiao = jiao;
    this.sayName = function () {
        alert(this.name);
    }
}
var cat = new Animal("元宝", 2, "maio~~~");
console.log(cat);
var dog = new Animal("球球", 3, "汪~~~"); 
dog.sayName();

工厂模式和构造函数模式的异同点

共同点:都是函数 ,都可以创建对象,都可以传参
区别:
工厂模式:
1.函数名是小写
2.没有new,
3.需要return语句
4.直接调用函数就可以创建对象

自定义构造函数:
1.函数名是大写(首字母)
2.有new
3.不需要return语句
4.通过new的方式来创建对象

new创建

var obj = new Object();
obj.name = "wu";
console.log(obj.name);
var obj2 = new Date();
console.log(obj2);

Object.create()创建

将 {name: ‘zhang’} 作为 新对象的原型, 保存在__proto__
obj 访问 name属性, 自己没有则沿着原型链开始向上寻找, 直到找到返回值, 或 没有找到返回undefined

var obj3 = Object.create({name: 'wu'})
console.log(obj3.name);
console.log(obj3.age);//undefined

2对象的方法

valueOf()返回当前对象原始值

var o = new Object();
o.valueOf() === o //true

toString()方法返回当前对象对应的字符串形式

var o1 = new Object();
o1.toString()

var o2 = {a:1};
o2.toString() 

//函数调用该方法返回的是函数本身的代码
function hq (argument) {
    // body... 
}
console.log(hq.toString());
var a = [1,2,3];
console.log(a.toString());
console.log(new Date().toString())
Object行为
数组将Array的元素转换为字符串,结果字符串被连接起来,用逗号分隔
布尔值如果布尔值为true,则返回"true",否则返回"false"
日期返回日期的文本表示形式
错误返回一个包含相关错误信息的字符串
函数返回如下格式的字符串,其中functionName是函数的名称 function functionName() { [native code] }
Number返回数字的文字表示形式
字符串返回String对象的值
默认{}返回"[object Object]"

对象和字符串之间的转换

var o1 ={
	name:"o1"
}
console.log(JSON.stringify(o1));
console.log(JSON.parse(JSON.stringify(o1)) === o1); // false

3.对象的属性

delete

delete可以删除对象自身的属性,不能删除继承来的属性

var obj = {
            name:"wu",
            age: 20
        }
        delete obj.name;
        console.log(obj);
        delete obj.toString;
        console.log(obj.toString);

判断一个对象中是否含有某个属性

  1. 使用in判断
    既可以判断自身的属性,也可以判断继承来的属性
  2. 使用hasOwnProperty判断
    只能判断自身有的属性,不能判断继承来的属性
    3)propertyIsEnumerable()
    检查一个属性是否属于某个对象自有属性,不包括继承来的属性,且该属性可枚举
//检测属性
var person = {name:"尔尔er", age: 20}
 //设置属性,并配置信息
    Object.defineProperty(person, "sex",{
        value:"女",
        enumerable:false
});

//in
console.log('name' in person);//true
console.log('sex' in person);//true
console.log('toString' in person);//true

//hasOwnProperty()
console.log(person.hasOwnProperty('name'));//true
console.log(person.hasOwnProperty('sex'));//true
console.log(person.hasOwnProperty('toString'));//false

//propertyIsEnumerable()
console.log(person.propertyIsEnumerable('name'));//true
console.log(person.propertyIsEnumerable('sex'));//false
console.log(person.propertyIsEnumerable('toString'));//false

delete可以删除对象自身的属性,不能删除继承来的属性

内置Object的defineProperty
有三个参数:操作的对象,要操作的属性(String类型),属性描述(对象类型)

        var obj = {name:'尔尔' ,age:18};
        function showData(data){
            document.querySelector('.name').innerHTML = obj.name;
            document.querySelector('.age').innerHTML = obj.age;
            document.querySelector('.gender').innerHTML = obj.gender;

        }
        showData(obj);
        setInterval(function(){
            obj.gender = Math.random();
        }, 1000)
        Object.defineProperty(obj, 'gender' , {
            enumerable:true,
            configurable:true,
            get: function(){
                return gender;
            },
            set: function(newValue){
                gender = newValue;
                showData(obj);//改变数据,页面上的数据更新显示
            }

        })
        obj.gender = '男';

三、函数

1.函数的三种定义方式

1.1函数声明

function fun(){
	console.log(1);
}

1.2函数表达式定义

var foo = function(){
    console.log(1);
}

1.3内置构造函数定义

不常用,无法实现递归(自己调用自己)

var f = new Function('x,y', 'console.log(x,y);')
2.函数调用

函数中的this指向函数的调用者,谁调用这个函数this就指向谁。this的指向和定义的位置无关,只和谁调用有关。

function f1(){
    console.log(this);
}
var o1 = {
    foo:function(){
        console.log(this);
    },
    fun:f1,
    obj:{
        f3:f1
    }
}
o1.foo();//o1
o1.fun();//o1
o1.obj.f3();//obj

函数调用

使用函数调用,this指向的是window

function f1(){
     console.log(this);
}
f1();//Window 

方法调用

this指向调用该方法的对象

 function f1(){
     console.log(this);
 }
 var obj = {
     f2:f1
 }
 obj.f2();//obj
3.this关键字

函数在执行的时候,函数内部会生成一个this。这个this指向谁在函数定义的时候是不确定的,函数执行时才能确定,谁调用它this就指向谁。

普通函数执行时,this指向的是全局对象window,函数作为对象中的方法调用时,this则指向调用这个方法的对象。

        function fn(){
            console.log(this);
        }
        fn();

        var obj = {
            name:'尔尔er',
            say: function(){
                console.log(this);
            }
        };
        obj.say();
4.构造函数
  1. 通过new 函数名来实例化对象的函数叫构造函数。构造函数就是函数,函数就是构造函数,使用function来声明。构造函数和普通函数的区别在于功能,构造函数主要用于实例化对象。
    2)在构造函数里面使用this指向构造函数的实例化对象
    3)使用new关键字来创建一个实例化对象
        // 构造函数
        function Cat(name,gender,age){
            this.name = name;
            this.gender = gender;
            this.age = age;
            this.say = function(){
               return `我叫${this.name},我是${this.gender},我${this.age}岁啦`;
            }
        }
        // 使用new创建一个Cat的实例化对象
        var cat = new Cat('元宝','弟弟',1);
        var cat2 = new Cat('蓝宝','弟弟',2);
        console.log(cat.say == cat2.say);//false

使用构造函数存在一个问题,每创建一个实例化对象,每个方法都要在每个实例上重新创建一遍,即在构造函数的不同实例上的同名函数是不相等的。

通过构造函数的原型prototype来扩展属性或方法

        function Cat(name,gender,age){
            this.name = name;
            this.gender = gender;
            this.age = age;
        }    
        Cat.prototype.say = function(){
               return `我叫${this.name},我是${this.gender},我${this.age}岁了`;
        }
         var cat = new Cat('元宝','弟弟',1);
         var cat2 = new Cat('蓝宝','弟弟',2);
        console.log(cat.say == cat2.say);//true

new关键字的作用
①分配一片空间
②让this指向这片空间(构造函数的实例)
③添加默认属性__proto__:{}
④在结尾默认返回this

5.方法劫持

作用:可以改变this的指向

call
两个或多个参数,第一个参数定义this的指向,后面的参数用于传参,使用散列的方式进行传参,函数立即执行。
apply
两个参数,第一个参数定义this的指向,第二个的参数用于传参,使用数组进行传参,函数立即执行。
bind
两个或多个参数,第一个参数定义this的指向,后面的参数用于传参,使用散列的方式进行传参。返回函数本身。bind的时候传的参数会预先传给返回的方法,调用方法时就不用再传参数了。

        var cat = {         
            action: function(name,age){
                console.log(`我叫${name},我${age}岁了,我要洗澡`);
            }
        };
        var dog = {

        };
        cat.action.call(dog,'南瓜',2);
        cat.action.apply(dog,['南瓜',2]);
        var dog1 = cat.action.bind(dog,'南瓜',2);
        dog1();
4.闭包

函数嵌套函数,参数和变量不会被垃圾回收机制回收

        function fn(){
            var i = 1;
            return function(){
                console.log(i++);
            }
        }
//引用在,空间不灭
        var f = fn();
        f();
        f();

四、原型和原型链

1) 所有的对象(null除外)都有一个属性__proto__,这个属性会指向该对象的原型。
2)构造函数有一个特有的属性prototype,指向他的的原型
3)在调用一个对象的属性和方法的时候,如果他自身没有这个属性或方法,就会在自己的原型(__proto__)上面找,如果没有找到,则会继续顺着__proto__原型去找,直到找到为止。
4)实例化对象的原型(__proto__)指向构造函数的prototype
5) 所有构造函数本身也是一个实例化对象,是Function这个内置的构造函数的实例化对象。

6)顶层对象是window

7)全局对象是GlobalThis

  1. js中一切皆为对象

__proto__和prototype的区别

__proto__是对象的内置属性,而prototype是函数的内置属性

可以使用isPrototypeOf()方法判断一个对象是否为参数对象的原型

var proto = Object.prototype;
console.log(proto.isPrototypeOf({}));

原型链

实例对象的__proto__属性指向其对应的原型对象。而在原型对象prototype上又有constructor__proto__属性,此时的__proto__又指向上级对应的原型对象,最终指向Object.prototype, 而Object.prototype.__proto__ === null。这就构成了原型链,而原型链最终都是指向null。当访问一个实例化对象的属性或方法时,会优先访问自己的,如果它自身没有,则沿着原型链一层一层找。

function Person(){
}
var person1 = new Person();
console.dir(Person);
console.log(Person.prototype === person1.__proto__);//true
console.log(Person.__proto__ === Function.prototype);//true
console.log(Function.__proto__ === Function.prototype);//true
 console.log(Person.prototype.__proto__ === Object.prototype);//true
console.log(Object.__proto__ === Function.prototype);//true
console.log(Object.prototype.__proto__);//null

通过构造函数创建的对象–>函数原型–>Object.prototype–> null 的指向,就是所谓的原型链;

五、JSON

JSON.stringfy()可以将JSON格式的数据序列化成字符串
JSON.parse()将string格式的数据解析成JSON格式

        var obj = {
            code: 200,
            error: 0,
            msg: 'SUCCESS',
            data: [{
                name: '尔尔er',
                age: 20
            }, {
                name: '尔尔er',
                age: 20
            }, {
                name: '尔尔er',
                age: 20
            }]
        };
        // window.localStorage将数据缓存到本地
        window.localStorage.setItem('data', JSON.stringify(obj));

        console.log(localStorage.getItem('data'));
        console.log(JSON.parse(localStorage.getItem('data')));
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值