JS学习四

对象

对象

万物皆对象,但是对象必须是一个具体的事物。例如:“明星”不是对象,“周星驰”是对象;“苹果”不是对象“这个苹果”是对象。
JS中,对象是一组无序的相关属性和方法的集合

对象是由属性和方法组成的

  • 属性:事物的特性,在对象中用属性来表示(常用名词)
  • 方法:事物的行为,在对象中用方法来表示(常用动词)

创建对象的三种方法

  • 利用字面量来创建对象
  • 利用new Object创建对象
  • 利用构造函数来创建对象

利用字面量来创建对象

对象字面量:就是{},里面包含了表达这个具体事物的属性和方法。
回忆:

  • ()是运算符,优先级最高;
  • []是数组字面量,用于创建数组;
  • {}是对象字面量,用于创建对象。
//1.利用字面量创建对象
//var obj={};//创建了一个空的对象

var obj = {
        uname: 'Lili',
        age: 18,
        sex: 'male',
        sayHi: function() { //匿名函数充当方法
            console.log('hi~');

        }
    }
    //注意点
    //(1)对象里的属性或者方法采用的是键值对的形式     键(属性名):值(属性值)
    //(2)多个属性或者方法之间用逗号隔开
    //(3)方法冒号后面跟的是一个匿名函数

//2.使用对象
//(1)调用对象的属性采取的是 对象名.属性名
console.log(obj.uname);
//(2)调用对象属性还有一种方法 对象名['属性名']
console.log(obj['age']);
//(3)调用对象的方法采取的是  对象名.方法名()  千万别忘记添加小括号
obj.sayHi(); //hi~

变量、属性、函数、方法总结:

//1.变量和属性的相同点:都是用来存储数据的
var num = 10;
var obj = {
        age: 10
    }
//不同点:
//变量 单独声明并赋值 使用的时候直接写变量名 单独存在
console.log(num);
//属性 在对象里面不需要声明使用的时候必须是对象.属性
console.log(obj.age);
//2.函数和方法的相同点:都是实现某种功能 做某件事
function fn() {

}
var obj = {
        fn: function() {

        }
    }
//不同点
//函数的单独声明并且调用的  函数名()  单独存在
fn();
//在对象里面 调用的时候是  对象.方法()
obj.fn();

利用new Object创建对象

//1. 利用new Object创建对象
var obj = new Object(); //创建了一个空的对象
//在空对象里追加属性和方法
obj.uname = 'Lili';
obj.age = 18;
obj.sex = 'male';
obj.satHi = function() {
        console.log('hi');
    }
//(1)利用等号赋值的方法来添加对象的属性和方法
//(2)每个属性和方法直接用分号结束

//2. 调用属性的两种方式
console.log(obj.uanme);
console.log(obj['sex']);
//调用方法
obj.sayHi();

利用构造函数来创建对象

为什么需要用到构造函数来创建对象?因为前面提到的两种创建对象的方法,一次仅仅可用创建一个对象。
有时候创建很多个对象的时候,里面很多的属性和方法大量是相同的,因此考虑运用函数的方法来重复这些相同的代码。我们就把这个函数称为构造函数。
换句话说:构造函数就是对象里面一些相同的属性和方法抽象出来封装到函数里。

//语法格式
//1.利用构造函数创建对象
function 构造函数名() {
    this.属性 =;
    this.方法 = function() {

    }
}
//2.调用
new 构造函数名();

举例

function Star(uname, age, sex) {
    this.name = uname;
    this.age = age;
    this.sex = sex;
    this.sing = function(sang) {
        console.log(sang);

    }
}
var ldh = new Star('刘德华', 18, '男');
console.log(typeof ldh); //object
console.log(ldh.name); //刘德华
console.log(ldh['sex']); //男
ldh.sing('冰雨');//冰雨

//(1)构造函数名首字母要大写
//(2)构造函数不需要return就可用返回结果
//(3)构造函数返回的是一个对象,利用typeof可用检测出来
//(4)构造函数与普通函数的不同之处在于:调用的时候前面多加了一个new;函数体里面属性和方法前面必须加上this;构造函数名首字母必须要大写

构造函数和对象的区别

  • 构造函数泛指一大类,相当于java语言里面的类;对象是一个特指
  • 利用构造函数创建对象的过程又称未类的实例化

new关键字

function Star(uname, age, sex) {
    this.name = uname;
    this.age = age;
    this.sing = function(sang) {
        console.log(sang);
    }
}
var ldh = new Star('刘德华', 18, '男');
//new 关键字执行过程
//1. new构造函数new Star可用在内存中创建了一个空对象
//2. this就会指向刚才创建的空对象
//3. 执行构造函数里面的代码 给这个空对象添加属性和方法
//4. 返回这个对象(所以构造函数里不需要return)

遍历对象属性

for...in用于对数组或者对象的属性进行循环操作

var obj = {
    name: 'pink老师',
    age: 18,
    sex: '男',
    fn: function() {}
}
for (var k in obj) {
    console.log(k); //k变量输出 得到的是属性名
    console.log(obj[k]); //obj[k]得到的是属性值  
}

内置对象

内置对象

  • js对象分为3种:自定义对象(var obj={})、内置对象、浏览器对象。
  • 前两种对象是js基础内容,属于ECMAScript,第三个浏览器对象是js独有的。讲js API的时候会讲。
  • 内置对象:js语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或者最
  • 基本而必要的功能(属性和方法),比如求最大值最小值,就不需要自己再去写相关的代码就可用直接利用内置对象得出。程序员将不关心内部是怎么实现的,只要拿出一组数来,就可以直接求出最大值和最小值。
  • 内置对象最大的优点,是帮助我们快速开发。
  • js提供了多个内置对象:MathDateArrayString

查文档

MDN/W3C
MDN官方网址https://developer.mozilla.org/zh-CN/
如何学习对象中的方法:
step1:查阅该方法的功能
step2:查看里面参数的意义和类型
step3:查看返回值的意义和类型
step4:通过demo进行测试

内置对象 Math()

Math.PI、 Math.max()、 Math.min()

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math

// Math数学对象 不是一个构造函数 不需要new一下就可用使用 而是直接用里面的属性和方法即可
console.log(Math.PI); // 3.141592653589793  一个属性 圆周率
console.log(Math.max(1, 99, 3)); // 9 一个方法 求最大值
// 如果给定的参数中至少有一个参数无法被转换成数字,则会返回 NaN。
console.log(Math.max(1, 99, 'pink老师')); // NaN
// 如果没有参数,则结果为 - Infinity
console.log(Math.max()); //-Infinity

利用对象封装自己的数学对象,里面有最大值、最小值、PI

//利用对象封装自己的数学对象,里面有最大值、最小值、PI
var myMath = {
    PI: 3.141592653589793,
    max: function() {
        var maxValue = arguments[0];
        for (var i = 1; i < arguments.length; i++) {
            if (arguments[i] > maxValue) {
                var temp = arguments[i];
                arguments[i] = maxValue;
                maxValue = temp;
            }
        }
        return maxValue;
    },
    min: function() {
        var minValue = arguments[0];
        for (var i = 1; i < arguments.length; i++) {
            if (arguments[i] < minValue) {
                var temp = arguments[i];
                arguments[i] = minValue;
                minValue = temp;
            }
        }
        return minValue;
    }
};
console.log(myMath.PI);
var a = myMath.max(1, 3, 99, 5);
console.log(a);
var b = myMath.min(1, 3, 99, 5);
console.log(b);

Math.abs()

console.log(Math.abs(1)); //1
console.log(Math.abs(-1)); //1
console.log(Math.abs('-1')); //1  隐式转换 会把字符串-1转换为数字型
console.log(Math.abs('pink')); //NaN

Math.floor()

向下取整

//(1)Math.floor() 向下取整 对于一切数都往最小了的取
console.log(Math.floor(1.1)); //1
console.log(Math.floor(1.5)); //1
console.log(Math.floor(1.9)); //1

console.log(Math.floor(-1.1));//-2
console.log(Math.floor(-1.5));//-2
console.log(Math.floor(-1.9));//-2

Math.ceil()

向上取整

//(2)Math.ceil() 向上取整 对于一切数都往最大了的取
console.log(Math.ceil(1.1)); //2
console.log(Math.ceil(1.5)); //2
console.log(Math.ceil(1.9)); //2

console.log(Math.ceil(-1.1)); //-1
console.log(Math.ceil(-1.5)); //-1
console.log(Math.ceil(-1.9)); //-1

Math.round()

//(3)Math.round() 四舍五入 对于一个数距离取距离起最近的整数,对于.5往大了取
console.log(Math.round(1.1)); //1
console.log(Math.round(1.5)); //2
console.log(Math.round(1.9)); //2

console.log(Math.round(-1.1)); //-1
console.log(Math.round(-1.5)); //-1
console.log(Math.round(-1.9)); //-2

随机数方法random() 重要

//1.Math对象随机方法 random() 返回一个随机小数x  0<=x<1;
//2.这个方法里面不跟参数
console.log(Math.random());
//4.若想得到两个数之间的随机整数 并且包含这两个数
//Math.floor(Math.random * (max - min + 1)) + min;

function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(getRandom(1, 10));
//5.随机点名
var arr = ['apple', 'banana', 'orange', 'pink', 'blue'];
console.log(arr[getRandom(0, 4)]);

案例1——猜数字游戏
随机生成一个1~10之间的数,并让用户输入一个数字

  • 如果用户输入的数字大于该数字则继续猜
  • 如果用户输入的数字小于该数字则继续猜
  • 如果用户输入的数字等于该数字则结束程序
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
var randNum = getRandom(1, 10);
while (true) {
    var num = prompt('请输入一个数字');
    if (num > randNum) {
        alert('输入的数字太大啦,继续猜吧!');
    } else if (num < randNum) {
        alert('输入的数字太小啦,继续猜吧!');
    } else {
        alert('输入正确,程序结束');
        break;
    }
}

案例2——要求用户输入1~50之间的一个数字,但是只要10次猜的机会

//要求用户输入1~50之间的一个数字,但是只要10次猜的机会
function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
var randNum = getRandom(1, 50);
for (var i = 10; i > 0; i--) {
    var num = prompt('请输入1~50之间的一个数');
    if (num > randNum) {
        alert('太大啦,继续猜吧!你还有' + (i - 1) + '次机会');
    } else if (num < randNum) {
        alert('太小啦,继续猜吧!你还有' + (i - 1) + '次机会');
    } else {
        alert('答案正确!');
        break;
    }
}

内置对象Date()

日期对象的使用

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date

//回忆
var arr = new Array(); //创建一个数组对象
console.log(arr); //[]
console.log(typeof arr); //object

var obj = new Object(); //创建一个对象实例
console.log(obj); //{}
console.log(typeof obj); //object
//Date() 日期对象 也是一个构造函数 必须用new来创建我们的日期对象
//1. Date()的使用 如果没有提供参数,那么新创建的Date对象表示实例化时刻的日期和时间。
var date = new Date();
console.log(date); //Fri Jan 21 2022 12:33:35 GMT+0800 (中国标准时间)
//2. 常用的写法
//写法1:数字型2022,2,21,或者是字符串型'2022-2-21 12:33:35'
var date1 = new Date(2022, 1, 21);
console.log(date1); // Fri Jan 21 2022 12:33:35 GMT+0800 (中国标准时间) 注意这里返回的是2月不是1月
var date2 = new Date('2022-1-21 12:33:35');
console.log(date2); //Fri Jan 21 2022 12:33:35 GMT+0800 (中国标准时间)
var date3 = new Date('2022/1/21/12:33:35');
console.log(date3); //Fri Jan 21 2022 12:33:35 GMT+0800 (中国标准时间)

日期格式化

//格式化日期 年 月 日
var date = new Date();
console.log(date.getFullYear()); //2022 返回当前的年
console.log(date.getMonth()); // 0 返回当前的月份 返回的月份比当前的月份少1  因为date.getMonth()获得当月(0-11)
// 所以要记得月份加1
console.log(date.getMonth() + 1); // 2
console.log(date.getDate()); // 21 返回当前的日
console.log(date.getDay()); // 5 返回当前星期几  星期天~星期6依次对应0123456
方法名说明代码
getFullYear()获取当年dObi. getFullYear()
getMonth()获取当月(0-11)dObj.getMonth()
getDate()获取当天日期dObj.getDate()
getDay()获取星期几(周日0 周六6)dObj.getDay()
getHours()获取当前小时dObj.getHours()
getMinutes()获取当前分钟dObj.getMinutes()
getSeconds()获取当前秒dObj.getSeconds()
//现在想写一个2022年1月21日星期五
var date = new Date(); //必须先实例化
var year = date.getFullYear();
var month = date.getMonth();
var dates = date.getDate();
var arr = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
var day = date.getDay();
console.log('今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]); //今天是:2022年2月21日 星期五
var date = new Date();//获取当前的时间所以不要传参数进去
//格式化 时 分 秒
console.log(date.getHours()); //13 得到当前的小时
console.log(date.getMinutes()); //6 得到当前的分钟
console.log(date.getSeconds()); //22 得到当前的秒数
//要求封装一个函数 返回当前的时分秒 格式:时:分:秒
function reTime() {
    var date = new Date();
    //格式化 时 分 秒
    var hour = date.getHours(); //13 得到当前的小时
    hour = hour < 10 ? '0' + hour : hour;

    var min = date.getMinutes(); //6 得到当前的分钟
    min = min < 10 ? '0' + min : min;

    var sec = date.getSeconds(); //22 得到当前的秒数
    sec = sec < 10 ? '0' + sec : sec;

    return hour + ':' + min + ':' + sec;
}
console.log(reTime()); //13:06:22

获取日期总的毫秒数

  • 获取Date总的毫秒数(过去到现在总的毫秒数)
  • Date对象是基于1970年1月1日(世界标准时间)起的毫秒数,经常利用总的毫秒数来计算时间,因为它更精确。
//获得Date总的毫秒数(时间戳)
//1. 通过valueOf()或者getTime()
var date = new Date();
console.log(date.valueOf()); //1576493997344
console.log(date.getTime()); //1576494010514
//2.简单写法(最常用的写法)
var date1 = +new Date(); //+new Date();返回的就是总的毫秒数
console.log(date1); //1576494090710
//3. H5新增,获得总的毫秒数 低版本的浏览器可能不兼容
console.log(Date.now()); //1576494168472
//毫秒数是永远不重复的

案例:倒计时(重点案例)

//倒计时案例
//用时间点a的毫秒数减去时间点b的毫秒数,
//再将其转换为月日年时分秒 转换公式如下
//d天=parseInt(总秒数/60/60/24);
//h小时=parseInt(总秒数/60/60%24);
//m分钟=parseInt(总秒数/60%60);
//s秒=parseInt(总秒数%60);
//注意:1s=1000ms
function countDown(time) {
    var nowTime = +new Date(); //返回当前时间总的毫秒数
    var inputTime = +new Date(time); //返回用户输入时间总的毫秒数
    var times = (inputTime - nowTime) / 1000; //times是剩余时间的总的秒数
    var d = parseInt(times / 60 / 60 / 24);
    d = d < 10 ? '0' + d : d;
    var h = parseInt(times / 60 / 60 % 24);
    h = h < 10 ? '0' + h : h;
    var m = parseInt(times / 60 % 60);
    m = m < 10 ? '0' + m : m;
    var s = parseInt(times % 60);
    s = s < 10 ? '0' + s : s;
    return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2019-12-16 20:30:00')); //00天00时37分42秒

内置对象Array()

数组的创建

之前提到过数组的创建方式

  • 字面量
  • new Array()
//创建数组的两种方式
//1.利用数组字面量
var arr = [1, 2, 3];
console.log(arr);

//2.利用new Arry()
var arr1 = new Array(); //创建一个空数组
console.log(arr1); //[]
var arr2 = new Array(2); //创建一个长度为2的空数组
console.log(arr2); //(2)[empty × 2] 里面有两个空的数组元素
var arr3 = new Array(2, 3); //这样写表示里面有两个数组元素,分别是2和3
console.log(arr3); //(2) [2, 3]

检测是否为数组的两种方式

之前提到过翻转数组,如下:

//翻转数组
function reverse(arr) {
    var arr1 = [];
    for (var i = arr.length - 1; i >= 0; i--) {
        arr1[arr1.length] = arr[i];
    }
    return arr1;
}
console.log(reverse([1, 2, 3])); //[3, 2, 1]
console.log(reverse(1, 2, 3)); //[]结果错误

调用函数的时候传入的实参必须是数组的形式,若输入的实参不是数组则会出现错误,因而需要对函数进行优化,判断传入的实参是否为数组。

检测是否为数组的方式如下:
方法1:

// 检测是否为数组
//(1)instanceof 运算符可以用来检测是否为数组
var arr = [];
var obj = {};
console.log(arr instanceof Array); //true
console.log(obj instanceof Array); //false

数组反转程序改进如下:

// 翻转数组
function reverse(arr) {
    if (arr instanceof Array) {
        arr1 = [];
        for (var i = arr.length - 1; i >= 0; i--) {
            arr1[arr1.length] = arr[i];
        }
        return arr1;
    } else {
        return '输入的参数必须是数组的形式如[1,2,3]';
    }
}
console.log(reverse([1, 2, 3])); //[3, 2, 1]
console.log(reverse(1, 2, 3)); //输入的参数必须是数组的形式如[1,2,3]

方法2:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

// 检测是否为数组
//(2)Array.isArray(参数) 该方法可以用来检测是否为数组
var arr = [];
var obj = {};
console.log(Array.isArray(arr)); //true
console.log(Array.isArray(obj)); //false

当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.

添加删除数组元素的方法

方法名说明返回值
push(参数1,…)末尾添加—个或多个元素,注意修改原敌组并返回新的长度
pop()删除数组最后—个元素,把数组长度减1无参数、修改原数组返回它删除元素的值
unshift(参数1,…)向数组的开头添加一个或更多元素,注意修改原数组并返回新的长度
shift()删除数组的第一个元素,数组长度减1无参数、修改原数组并返回第一个元素的值
//添加、删除数组元素的方法
//1.push() 在我们数组的末尾添加一个和多个数组元素   
var arr = [1, 2, 3];
var n = arr.push(4, 'pink'); //n记录的是新数组的长度
console.log(arr); // [1, 2, 3, 4, "pink"]
console.log(n); //5
//(1)push可以给数组末尾追加新的元素
//(2)push里的参数直接跟数组元素
//(3)push完毕之后,返回的结果是新数组的长度
//(4)原数组也会发生变化

//2.unshift在我们数组的开头添加一个或多个数组元素
var n = arr.unshift('red', 'purple');
console.log(arr); //["red", "purple", 1, 2, 3, 4, "pink"]
console.log(n); //7
//(1)unshift是可以给数组前面追加新的元素
//(2)unshift()的参数直接写数组元素就可以了
//(3)unshift完毕之后,返回的结果是新数组的长度
//(4)原数组也会发生变化

//3.pop()它可以删除数组的最后一个元素
var m = arr.pop(); //m中存储的是被删除的那一个元素
console.log(arr); //["red", "purple", 1, 2, 3, 4]
console.log(m); //'pink'
//(1)pop是可以删除数组的最后一个元素,记住一次只能删除一个元素
//(2)pop()没有参数
//(3)pop完毕之后,返回的结果是删除的那个元素
//(4)原数组也会发生变化

//4.shift()它可以删除数组的第一个元素
var m = arr.shift(); //m中存储的是被删除的那一个元素
console.log(arr); //["purple", 1, 2, 3, 4]
console.log(m); //'red'
//(1)shift是可以删除数组的第一个元素,记住一次只能删除一个元素
//(2)shift()没有参数
//(3)shift完毕之后,返回的结果是删除的那个元素
//(4)原数组也会发生变化

案例:
筛选数组

//有一个包含工资的数组[1500,1200,2000,2100,1800],要求把数组中工资超过2000的删除,剩余的放到新数组里面。
var arr = [1500, 1200, 2000, 2100, 1800];
var new_arr = [];
for (var i = 0; i < arr.length; i++) {
    if (arr[i] < 2000) {
        new_arr.push(arr[i]);
    }
}
console.log(new_arr); // [1500, 1200, 1800]

数组排序reverse()和sort()

方法名说明是否修改原数组
reverse()颠倒数组中元素的顺序,无参数该方法会改变原来的数组返回新数组
sort()对数组的元素进行排序该方法会改变原来的数组返回新数组

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse

//1.反转数组
var arr = ['pink', 'red', 'blue'];
arr.reverse();
console.log(arr); //["blue", "red", "pink"]

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

//2.数组排序(冒泡排序)
var arr1 = [3, 4, 7, 1];
arr1.sort();
console.log(arr1); //[1, 3, 4, 7]

//但是sort()只适用于单数,如果出现多位数则会出现一下情况
var arr2 = [13, 4, 77, 1, 7];
arr2.sort();
console.log(arr2); //[1, 13, 4, 7, 77]

//解决方案如下写法固定记住即可
var arr2 = [13, 4, 77, 1, 7];
arr2.sort(function(a, b) {
    return a - b; //按照升序方式排列
});
console.log(arr2); //[1, 4, 7, 13, 77]

var arr2 = [13, 4, 77, 1, 7];
arr2.sort(function(a, b) {
    return b - a; //按照降序方式排列
});
console.log(arr2); //[77, 13, 7, 4, 1]

数组索引indexOf()和lastIndexOf()

方法名说明返回值
indexOf()数组中查找给定元素的索引(第一个开始查找)如果存在返回索引号如果不存在,则返回-1。
lastlndexOf()从查找数组中的索引(从最后一个开始查找)如果存在返回索引号如果不存在,则返回-1
//返回数组元素索引号方法
//indexOf(数组元素)返回该数组元素的索引号  从前往后查找
var arr = ['red', 'green', 'blue', 'pink'];
console.log(arr.indexOf('blue')); //2
//只返回第一个满足条件的索引号
var arr = ['red', 'green', 'blue', 'pink', 'blue'];
console.log(arr.indexOf('blue')); //2  依然返回2
//它如果在该数组中找不到对应的元素则返回-1
var arr = ['red', 'green', 'pink'];
console.log(arr.indexOf('blue')); //-1

//lastIndexOf(数组元素)返回该数组元素的索引号  从后往前查找
var arr = ['red', 'green', 'blue', 'pink'];
console.log(arr.lastIndexOf('blue')); //2
//只返回第一个满足条件的索引号
var arr = ['red', 'green', 'blue', 'pink', 'blue'];
console.log(arr.lastIndexOf('blue')); //4  因为是从后往前查找
//它如果在该数组中找不到对应的元素则返回-1
var arr = ['red', 'green', 'pink'];
console.log(arr.lastIndexOf('blue')); //-1

数组去重
错误示例:

//有一个数组['c','a','z','a','x','a','x','c','b']要求:去除数组中重复的元素
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'];
var new_arr = [];
for (var i = 0; i < arr.length; i++) {
    if (arr[i] in new_arr) {
        continue;
    } else {
        new_arr.push(arr[i]);
    }
}
console.log(new_arr); //["c", "a", "z", "a", "x", "a", "x", "c", "b"]  出现错误
//错误原因:x in arr 这里要注意的是判断数组的话 x表示的是下标,这个意思就是arr数组中有下标为x的元素吗
//x in obj 现在的x表示的是对象的属性,这个意思是obj中有没有x这个属性

写法1:

// 有一个数组['c','a','z','a','x','a','x','c','b']要求:去除数组中重复的元素
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'];
var new_arr = [];
for (var i = 0; i < arr.length; i++) {
    var flag = 0;
    for (var j = 1; j < new_arr.length; j++) {
        if (arr[i] == new_arr[j]) {
            flag = 1;
            break; //结束内层for循环,继续下一轮外层循环
        }
    }
    if (flag == 0) {
        new_arr.push(arr[i]);
    }
}
console.log(new_arr); //"c", "a", "z", "x", "c", "b"]

方法2:(利用indexOf)

//有一个数组['c','a','z','a','x','a','x','c','b']要求:去除数组中重复的元素
//利用indexOf
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'];
var new_arr = [];
for (var i = 0; i < arr.length; i++) {
    if (new_arr.indexOf(arr[i]) == -1) {
        new_arr.push(arr[i]);
    }
}
console.log(new_arr);//["c", "a", "z", "x", "b"]

封装成函数得到:

//有一个数组['c','a','z','a','x','a','x','c','b']要求:去除数组中重复的元素
//利用indexOf
//封装成函数
function unique(arr) {
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        if (newArr.indexOf(arr[i]) === -1) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
}
var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']);
console.log(demo); //["c", "a", "z", "x", "b"]

将数组转化成字符串toString()和join()

方法名说明返回值
toString()把数组转换成字符串,逗号分隔每一项返回一个字符串
join(‘分隔符’)方法用于把数组中的所有元素转换为一个字符串返回一个字符串
concat()连接两个或多个数组不影响原数组返回一个新数组
slice()数组截取slice(begin, end)返回被截取项目的新数组
splice()数组删除splice(第几个开始,要删除个数)返回被删除项目的新数组注意,这个会影响原数组
//数组转化为字符串
//1. toString() 将数组里面的元素转化成字符串,中间用逗号连接
var arr = [1, 2, 3];
console.log(arr.toString()); //1,2,3
//2. join(['分隔符'])
var arr1 = ['green', 'blue', 'pink'];
console.log(arr1.join()); //green,blue,pink 若不写分隔符,默认用逗号分割
console.log(arr1.join('-')); //green-blue-pink
console.log(arr1.join('&')); //green&blue&pink

以下数组方法

  • concat()方法

用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
语法:var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

var arr1 = [1, 2, 3];
var arr2 = ['pink', 'red', 'blue'];
var arr3 = [7, 8, 9];
//1.连接两个数组
var arr4 = arr1.concat(arr2);
console.log(arr4); //[1, 2, 3, "pink", "red", "blue"]
var arr5 = arr2.concat(arr1);
console.log(arr5); //["pink", "red", "blue", 1, 2, 3]

//2.连接三个数组
var arr6 = arr1.concat(arr2, arr3);
console.log(arr6); //[1, 2, 3, "pink", "red", "blue", 7, 8, 9]

//3. 将数值连接到数组
var arr7 = arr1.concat(1);
console.log(arr7); //[1, 2, 3, 1]
var arr8 = arr1.concat(1, [2, 3]);
console.log(arr8); //[1, 2, 3, 1, 2, 3]

//4. 返回的是新数组,原数组保持不变
console.log(arr1); //[1, 2, 3]
console.log(arr2); //['pink', 'red', 'blue']
console.log(arr3); //[7, 8, 9]
  • slice() 方法

返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
语法:arr.slice([begin[, end]])
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

var arr = [1, 'pink', 3, 6, 'blue', 'orange', 'apple'];
//1.无参数
var newArr = arr.slice(); //全部
console.log(newArr); // [1, "pink", 3, 6, "blue", "orange", "apple"]

//2.一个参数 默认是begin参数  end 被省略,则 slice 会一直提取到原数组末尾。
var newArr = arr.slice(0); //下标从0开始到结束
console.log(newArr); // [1, "pink", 3, 6, "blue", "orange", "apple"]

var newArr = arr.slice(2); //相当于从索引号2开始一致到结束
console.log(newArr); //[3, 6, "blue", "orange", "apple"]

//3.两个参数
var newArr = arr.slice(2, 4); //相当于索引号[2,4)
console.log(newArr); //[3, 6]

var newArr = arr.slice(-3, -1); //相当于索引号[-3, -1)  -1表示倒数第一个  -3表示倒数第三个
console.log(newArr); //["blue", "orange"]

//4. end 大于数组的长度,slice 也会一直提取到原数组末尾。
var newArr = arr.slice(2, 10); //相当于索引号[2,10)
console.log(newArr); //[3, 6, "blue", "orange", "apple"]
  • splice()方法

通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
语法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
start​:指定修改的开始位置(从0计数)。
如果超出了数组的长度,则从数组末尾开始添加内容;
如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n);
如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
deleteCount(可选参数):整数,表示要移除的数组元素的个数。
如果 deleteCount 大于 start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。
如果 deleteCount 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
item1, item2, … (可选)要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
返回值:由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。

//语法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
var arr = ['pink', 'blue', 'orange', 'apple', 'banana'];

//1.从第 2 位开始删除 0 个元素,插入1
var remove = arr.splice(2, 0, 1);
console.log(remove); //[]
console.log(arr); //["pink", "blue", 1, "orange", "apple", "banana"]

//2.从第 2 位开始删除 0 个元素,插入aaa
var remove = arr.splice(2, 0, 'aaa');
console.log(remove); //[]
console.log(arr); //["pink", "blue", "aaa", 1, "orange", "apple", "banana"]

//3. 从第 3 位开始删除 1 个元素
var remove = arr.splice(3, 1);
console.log(remove); //[1]
console.log(arr); //["pink", "blue", "aaa", "orange", "apple", "banana"]

//4.从第 2 位开始删除 1 个元素,插入“bbb”
var remove = arr.splice(2, 1, 'bbb');
console.log(remove); //["aaa"]
console.log(arr); //["pink", "blue", "bbb", "orange", "apple", "banana"]

//5.从第 0 位开始删除 3 个元素,插入"ccc"、"ddd"、"eee"和"fff"
var remove = arr.splice(0, 3, 'ccc', 'ddd', 'eee', 'fff');
console.log(remove); //["pink", "blue", "bbb"]
console.log(arr); //["ccc", "ddd", "eee", "fff", "orange", "apple", "banana"]

//6.从倒数第 2 位开始删除 1 个元素
var remove = arr.splice(-2, 1);
console.log(remove); //["apple"]
console.log(arr); //["ccc", "ddd", "eee", "fff", "orange", "banana"]

//7. 从第 3 位开始删除所有元素
var remove = arr.splice(3);
console.log(remove); // ["fff", "orange", "banana"]
console.log(arr); //["ccc", "ddd", "eee"]

内置对象 String()

基本包装类型String、Number和Boolean

//基本包装类型
var str = 'andy';
console.log(str.length); //4
//提问:
//JS的数据类型分:简单数据类型(Number,String,Boolean,Underfined,Null)和复杂数据类型(object)
//而只有复杂数据类型才有属性和方法,字符串作为简单数据类型为什么也会有属性(str.length)和方法呢
//回答:
//这里涉及到JS里面的基本包装类型:把简单(基本)数据类型包装为复杂数据类型 这样基本数据类型就有属性和方法了
//step1:把简单数据类型包装为复杂数据类型
var temp = new String('andy');
//step2:把临时变量值给str
str = temp;
//step3:销毁这个临时变量
temp = null;

//说明:其实不光是字符串String,对于Number和Boolean都可以进行包装

字符串的不可变

字符串的不可变性:指的是里面的值不可变,虽然看上去可以改变内容但其实是地址变了,即在内存中新开辟了一个内存空间。

//字符串的不可变性
var str = 'andy';
console.log(str); //andy
str = 'red';
console.log(str); //red

字符串所有的方法都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串,即新开辟一个内存空间存放字符串。

根据字符返回位置

方法名说明
indexOf(‘要查找的字符’,开始的位置)返回指定内容在元字符串中的位置,如果找不到就返回-1,开始的位置是index索引号
lastlndexOf()从后往前找,只找第一个匹配的
//字符串对象 根据字符返回位置
//indexOf与之前数组的使用方法完全一致,前面数组没讲的用法,这里继续补充,依然适用于数组和字符串
//语法:str.indexOf('要查找的字符',[起始位置])     注:起始位置是可选参数  注意只有begin没有end
var str = "改革春风吹满地,春天来了";
console.log(str.indexOf('春')); //2    默认从起始位置开始查找
console.log(str.indexOf('春', 3)); //8  从索引号是3的位置往后查找
//lastIndexOf与indexOf类似
console.log(str.lastIndexOf('春')); //8    默认从末尾开始往前查找
console.log(str.lastIndexOf('春', 1)); //-1    从索引号为1的位置往前查找,结果是查找不到
console.log(str.lastIndexOf('春', 5)); //2    从索引号为5的位置往前查找

案例:
返回字符位置
要求:返回字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
方法1:

//要求:返回字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
var str = 'abcoefoxyozzopp';
var index = 0;
var site = [];
while (index < str.length) {
    if (str.indexOf('o', index) != -1) {
        index = str.indexOf('o', index);
        site.push(index);
        index = index + 1;
    } else {
        break;
    }
}
console.log(site); //[3, 6, 9, 12]
console.log(site.length); //4

方法2:

//要求:返回字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
var str = 'abcoefoxyozzopp';
var index = str.indexOf('o');
var num = 0;
while (index !== -1) {
    console.log(index);
    num++;
    index = str.indexOf('o', index + 1) //新的一轮查找
}
console.log(num);//4
//返回数组['red','blue','red','green','pink','red']求red出现的位置和次数
var arr = ['red', 'blue', 'red', 'green', 'pink', 'red'];
var index = arr.indexOf('red');
var num = 0;
while (index !== -1) {
    console.log(index); //0 2 5
    num++;
    index = arr.indexOf('red', index + 1)
}
console.log(num); //3

根据位置返回字符(重点)

方法名说明使用
charAt(index)返回指定位置的字符(index字符串的索引号)str.charAt(0)
charCodeAt(index)获取指定位置处字符的ASCII码 (index索引号)str.charCodeAt(0)
str[index]获取指定位置处字符HTML5,IE8+支持和charAt()等效
//根据位置返回字符
//1.charAt(index) 根据位置返回字符
var str = 'andy';
console.log(str.charAt(3)); //y
//遍历所有的字符
for (var i = 0; i < str.length; i++) {
    console.log(str.charAt(i)); //a n d y
}
//2.charCodeAt(index) 返回相应索引号的字符的ASCII值  目的:判断用户按下了哪个按键
console.log(str.charCodeAt(0)); //97
//3.str[index]获取指定位置处字符  H5和ie8+支持 存在兼容性问题,和charAt()效果相同
console.log(str[0]); //a

案例:
统计出现次数最多的字符
案例前的小知识点补充:

// 有一个对象
var obj = {
    age: 8
}
console.log(obj['age']); //8
console.log(obj['sex']); //undefined
console.log(obj.age); //8
console.log(obj.sex); //undefined
// age 和 sex都是属性名
// 代表空的、否定的值都会被转化为false, 如:''、0、NaN、null、underfined
// 其余值都会被转化为true

// 因此可以通过以下方法来判断某个对象是否包含以下属性,如:
if (obj['age']) {
    console.log('里面有该属性');
} else {
    console.log('没有该属性');
}
// 也可以
if (obj.age) {
    console.log('里面有该属性');
} else {
    console.log('没有该属性');
}

案例要求:
判断一个字符串’abcoefoxyozzopp’出现次数最多的字符,并统计其次数

// 判断一个字符串'abcoefoxyozzopp'出现次数最多的字符,并统计其次数
str = 'abcoefoxyozzopp';
var obj = {};
for (var i = 0; i < str.length; i++) {
    var chars = str.charAt(i); // chars是一个字符串,两边带双引号的那种,所以下面选用obj[chars]而不是obj.chars
    if (obj[chars]) {
        obj[chars]++;
    } else {
        obj[chars] = 1;
    }
}
console.log(obj); //{a: 1, b: 1, c: 1, o: 4, e: 1, …}

// 遍历对象
var max = 0;
var ch = '';
for (var k in obj) {
    // k是属性
    // obj[k]是属性值
    if (obj[k] > max) {
        max = obj[k];
        ch = k;
    }
}
console.log(max); // 4
console.log(ch); // o

字符串操作方法(重点)

方法名说明
concat(str1,str2,str3…)concat()方法用于连接两个或多个字符串。拼接字符串,等效于+,+更常用
substr(start,length)从start位置开始(索引号), length取的个数重点记住这个
slice(start, end)从start位置开始,截取到end位置,end取不到(他们俩都是索引号)
substring(start, end)从start位置开始,截取到end位置,end取不到基本和slice相同但是不接受负值
  • concat(‘字符串1’,‘字符串2’,…)和substr(‘截取的起始位置’,‘截取几个字符’)
// 字符串操作方法
// 1.concat('字符串1','字符串2',...) 和之前数组里的用法一致
// 相当于字符串拼接中的'+' ,'+'更常用
var str = 'andy';
console.log(str.concat('red')); //andyred
console.log(str);//andy  原字符串不变

// 2. substr('截取的起始位置','截取几个字符')
// 相当于数组中的splice()
var str1 = '改革春风吹满地';
console.log(str1.substr(2, 2)); // 春风
console.log(str1);//'改革春风吹满地'   原字符串不变
  • 补充slice和substring
// 3. slice('截取的起始位置','截取的结束位置')
var str1 = '改革春风吹满地';
console.log(str1.slice(2, 2)); // 相当于[2,2)**啥都取不到**
console.log(str1.slice(2, 4)); // 春风    相当于[2,4)
console.log(str1); //'改革春风吹满地'   原字符串不变

substring基本和slice相同但是不接受负值

  • replace(‘被替换的字符串’,‘替换为的字符串’)
// 1.替换字符串replace('被替换的字符串','替换为的字符串') 它只会替换第一个字符
var str = 'andyandy';
console.log(str.replace('a', 'b')); // bndyandy
console.log(str);// andyandy  原字符串不变

案例:要求把’abcoefoxyozzopp’里的’o’全部替换成’*’

// 方法1:
var str1 = 'abcoefoxyozzopp';
for (var i = 0; i < str1.length; i++) {
    chars = str1.charAt(i);
    if (chars === 'o') {
        str1 = str1.replace('o', '*');
    }
}
console.log(str1); // abc*ef*xy*zz*pp

// 方法2:
var str2 = 'abcoefoxyozzopp';
while (str2.indexOf('o') !== -1) {
    str2 = str2.replace('o', '*');
}
console.log(str2);// abc*ef*xy*zz*pp
  • toUpperCase转换成大写、toLowerCase转换成小写

将调用该方法的字符串值转换为大写形式,并返回。toUpperCase 方法不影响字符串本身的值因为JavaScript的strings是immutable的(不可改变的),toLowerCase类似。

var str = 'AabcdefDDDghijk MMlmn op!!~~';
console.log(str.toUpperCase()); //AABCDEFDDDGHIJK MMLMN OP!!~~

var str1 = 'AabcdefDDDghijk MMlmn op!!~~';;
console.log(str1.toLowerCase()); //aabcdefdddghijk mmlmn op!!~~

案例
给定一个字符串,如: "abaasdffggghhjjikkgfddsssss3444343”,问题如下:1、字符串的长度
2、取出指定位置的字符,如:0,3,5,9等
3、查找指定字符是否在以上字符串中存在,如:i ,c ,b等
4、替换指定的字符,如:g替换为22,ss替换为b等操作方法
5、截取指定开始位置到结束位置的字符串,如::取得1-5的字符串
6、找出以上字符串中出现次数最多的字符和出现的次数

var str = 'abaasdffggghhjjkkgfddsssss3444343';
// 1
len = console.log(str.length); //33
// 2
ch = console.log(str.charAt(9)); //g
// 3
if (str.indexOf('i') === -1) {
    console.log('没有字符i');

} else {
    console.log('有字符i');

}
// 4
while (str.indexOf('g') !== -1 || str.indexOf('s') !== -1) {
    str = str.replace('g', '22');
    str = str.replace('s', 'b');
}
console.log(str); //abaabdff222222hhjjkk22fddbbbbb3444343

// 5
console.log(str.slice(1, 6));

// 6
var str = 'abaasdffggghhjjkkgfddsssss3444343';
var obj = {};
for (var i = 0; i < str.length; i++) {
    chars = str.charAt(i);
    if (obj[chars]) {
        obj[chars]++; //更改属性值
    } else {
        obj[chars] = 1; //给属性赋值
    }
}
console.log(obj); //{3: 3, 4: 4, a: 3, b: 1, s: 6, d: 3, f: 3, …}

var max = 0;
var ch = '';
for (var k in obj) {
    if (obj[k] > max) {
        max = obj[k];
        ch = k;
    }
}
console.log(max); // 6
console.log(ch); // s

简单类型和复杂类型

简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型

  • 值类型∶简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型string , number , boolean ,undefined , null
//  简单数据类型null返回的是一个空的对象
var timer = null;
console.log(typeof timer);//  object
//  如果有个对象我们打算以后存储为对象,暂时没有想好放啥,这个时候就给null
  • 引用类型∶复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等

堆和栈

堆栈空间分配区别

  • 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。简单数据类型存放到栈里面。
  • 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,如程序员不释放,由垃圾回收机制回收,复杂数据类型存放到栈里面。
  • 注意:JavaScript中没有堆栈的概念,通过堆栈的方式,可以让大家更容易理解代码的一些执行方式,便于将来学习其他语言

简单类型的内存分配

  • 值类型(简单数据类型) :string , number , boolean , undefined , null
  • 值类型变量的数据直接存放在变量(栈空间)中
  • 简单数据类型:是存放在栈里面,在栈里面直接开辟一个空间存放的是值
  • 复杂数据类型:首先在栈里面存放地址(16进制表示 系统自己分配,这个地址指向堆里面的数据
    在这里插入图片描述

复杂类型的内存分配

  • 引用类型(复杂数据类型):通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
  • 引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

简单类型传参

函数的形参也可以看做是一个变量,当把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。

function fn(a) {
	a++;
	console.log(a);
}
var x = 10;
fn (x); // 11
console.log(x);  // 10

简单数据类型传参

复杂类型传参

函数的形参也可以看作是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保持的堆地址复制给了形参,形参和实参其实保存的是同一个地址,所以操作的是同一个对象;

function Person(name) {
            this.name = name;
        }

        function f1(x) { // x=p
            console.log(x.name); // 2.刘德华 
            x.name = '张学友';
            console.log(x.name); // 3.张学友
        }
        var p = new Person('刘德华');
        console.log(p.name); // 1.刘德华
        f1(p);
        console.log(p.name); // 4.张学友

1、2
在这里插入图片描述
3、4
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值