目录
* .charAt(索引);----->取字符串中第几个值,返回值是指定索引位置的字符串,超出索引,结果是空字符串。
* .concat("字符串1","字符串2",...);--->拼接。
* .indexOf(要找的字符串,[从某个位置开始的索引]);->返回的是这个字符串的索引值,没找到则返回-1。
* .replace("原来的字符串","新的字符串");--->用来替换字符串的
* .slice(开始的索引,结束的索引);从索引5的位置开始提取,到索引为10的前一个结束,没有10,并返回这个提取后的字符串
* .split("中间间隔的字符串(这个字符串会消失)",切割后留下的个数);--->切割字符串,这里很多时候要用循环。
* .substr(开始的位置,新字符串的个数);--->返回的是截取后的新的字符串。
* .substring(开始的索引,结束的索引);--->返回截取后的字符串,不包含结束的索引的字符串。
* .toLocaleLowerCase();--->转小写
Array.isArray(对象)---->判断这个对象是不是数组。(静态方法)
every-->在括号里传入一个参数,这个参数是函数。每个元素都需通过这个函数的测试。返回布尔类型值。
filter()-有一个数组,传入一个函数测试数组中的元素,最后返回满足测试条件的元素,把他们放到新的数组中。
push(值)-把值追加的数组中,返回值是追加数据后的长度。
pop()--删除数组中最后一个值,返回值就是数组中最后一个值。
unshift--向数组中第一个元素前面插入一个元素,返回值是插入数据后的长度。
forEach(function())--用于遍历数组,相当于for循环
join("字符串")--数组元素中间都加某个字符串,返回的是字符串
map(函数)--数组中每个元素都要执行这个函数,把执行之后的结果重新、全部放在一个新的数组中。
slice(开始的索引,结束的索引)--把截取的数组数值放在新数组中,但不包括结束的索引对应值。
splice(开始位置的索引,要删除元素的个数,替换元素的值)--一般用于删除数组中某个元素,或替换元素,或在某个位置添加元素。
-----------(黑马初级js课程第五、六天的内容以及高级课程)---------------
编程思想:把一些生活中做事的经验融入到程序中。
面向过程:凡事都要亲力亲为,每件事的具体过程都要知道,注重的是过程。
面向对象:根据需求找对象,所有的事都用对象来做,注重的是结果。
面向对象特性:封装,继承,多态 (抽象性)。
js不是面向对象的语言,但是可以模拟面向对象的思想。 js是一门基于对象的语言。
万物皆对象。什么是对象?
对象是某一个东西,具象的。人不是对象,Bella这个人就是对象。狗不是对象,我的狗就是对象。
分析对象的特点:特征和行为。
bella的特征:姓名、性别、年龄、肤色... =》就是属性
bella的行为:走路、说话、学习、跳舞... =》就是方法
一、没有对象--创建对象。
1、有三种方法:
- 调用系统的构造函数创建对象。var 变量名 =new Object();
- 自定义构造函数创建对象。(结合第一种和需求通过工厂模式创建对象)
- 字面量创建对象。
方法一:调用系统的构造函数创建对象
step1:
var obj =new Object();
new Object创建了一个对象,把它当到声明的变量里面了。这也叫实例化对象。
对象有属性和方法,所以接下来添加属性和方法。
step2:如何添加属性?点语法=》对象.属性名=属性值
obj.name ="bella";
obj.age=27;
step3:如何添加方法?点语法=》对象.方法名=函数
obj.eat =function(){
console.log("我喜欢吃榴莲");
};
obj.play=function(){
console.log("我喜欢玩泥巴");
}
step4:如何获取输出?对象.名称
console.log(obj.name); console.log(obj.age);
obj.eat;//我想让她吃
练习:创建一个手机对象,手机有型号,有颜色,可以打电话和发短信
var phone=new Object();
phone.size="iphone8";
phone.color="黑色";
phone.call=function () {
console.log("打电话");
};
phone.sendMessage=function () {
console.log("你干啥捏,我烧锅炉呢");
};
phone.call();
phone.sendMessage();
工厂模式创建对象:
如何一次性创建多个对象?--写一个函数,把创建对象的代码封装在这个函数中。
function createObject(name,age) {
var obj = new Object();//创建对象
//添加属性
obj.name = name;
obj.age = age;
//添加方法
obj.sayHi = function () {
console.log("阿涅哈斯诶呦,我叫:" + this.name + "我今年:" + this.age);
};
//返回对象
return obj;
}
//创建人的对象
var per1 = createObject("小芳",20);
per1.sayHi();
//创建一个人的对象
var per2 = createObject("小红",30);
per2.sayHi();
创建了createObject函数,里面定义了对象的属性和方法,返回这个对象。以后用只需要调用这个方法,并带上实参即可。同时,总结以下几点:
1、有同一类属性的不同个体可以封装成一个函数。
2、添加属性原本是直接写具体值,现在是用形参代替,在后期调用时,给实参。
3、函数名的形参和调用时候写的实参注意对应。
以上方法的对象全是Object。没办法细化区分。但是方法二自定义构造函数创建对象可以解决这个问题。
因为,这方法可以自己定义是Person类型、还是Dog类型。
方法二:自定义构造函数创建对象
(函数和构造函数的区别:首字母是否大写。用起来是一样的。)
1、先自定义一个构造函数。
function 函数名(形参1,形参2,...){
this.属性名=形参1;
this.属性名=形参2;
this.方法名=function(){} ...
}
2、再使用这个自定义的构造函数创建对象。
var obj=new Person("小明",10);
<script>
//自定义构造函数创建对象,我要自己定义一个构造函数,自定义构造函数,创建对象
//函数和构造函数的区别;名字是不是大写(首字母是大写)
function Person(name,age) {
this.name=name;
this.age=age;
this.sayHi=function () {
console.log("我叫:"+this.name+",年龄是:"+this.age);
};
}
//自定义构造函数创建对象:先自定义一个构造函数,创建对象
var obj=new Person("小明",10);
console.log(obj.name);
console.log(obj.age);
obj.sayHi();
var obj2=new Person("小红",20);
console.log(obj2.name);
console.log(obj2.age);
obj2.sayHi();
console.log(obj instanceof Person);
console.log(obj2 instanceof Person);
//自定义狗的构造函数,创建对象
function Dog(name,age,sex) {
this.name=name;
this.age=age;
this.sex=sex;
}
var dog=new Dog("大黄",20,"男");
console.log(dog instanceof Person);//false
console.log(dog instanceof Dog);
</script>
自定义构造函数创建对象做了四件事:
1、在内存中申请了一块空闲空间,存储创建的新的对象。
2、把this设置为当前对象。
3、设置对象的属性和方法。
4、把this这个对象返回。
工厂模式和自定义构造函数的共同点和区别:
先来回顾一下三种创建对象的方式:
<script>
// 1、字面量创建实例对象
var per1={
name:"kakaxi",
age:22,
hear:"black",
eat:function(){
},
read:function(){
}
}
// 2、调用系统构造函数
var per2=new Object();
per2.name="bella";
per2.age=11;
per2.sex="女";
per2.eat=function(){
},
per2.read=function(){
}
//工厂模式创建对象
function creatPerson(){
var obj=new Object(name,age);
obj.name=name;
obj.age=22;
obj.play=function(){
console.log("玩游戏")
}
return obj;
}
var per4=creatPerson("小明",20);
// 3、自定义构造函数
function per(name,age,sex){
this.name=name;
this.age;
this.sex;
this.eat=function(){
}
}
var per3=new per("diao",22,"女");
* 共同点:都是函数,都可以创建对象,都可以传入参数。
* 工厂模式:
* 函数名首字母是小写
* 有new,
* 有返回值
* new之后的对象是当前的对象(实例化后的对象)
* 直接调用函数就可以创建对象
* 自定义构造函数:(常用)
* 函数名首字母是大写
* 没有new
* 没有返回值
* this是当前的对象
* 通过new的方式来创建对象
方法三:字面量创建对象
var obj2={
name:"小明",
age:20,
sayHi:function () {
console.log("我是:"+this.name);
},
eat:function () {
console.log("吃了");
}
};
obj2.sayHi();
obj2.eat();
补充:1、字面量创建对象的缺陷:是一次性的对象。
如果前两种方法。只要在调用的时候,设置不同的值。而在方法三种,改name的时候,直接改了源码的值,被写死了。
2、点语法: 对象.名字=值; 对象.名字=函数;
如果对象的一个属性之前没有定义,只要它使用了点语法了,它即是存在的。
即:obj.height即是存在的,不需要提前定义。
3、js是一种动态类型语音:
- 代码(变量)只有执行到这个位置的时候,才知道这个变量中到底存储的是什么,如果是对象,就有对象的属性和方法,如果是变量就是变量的作用。
- 对象没有什么,只要点了,通过点语法,那么就可以为对象添加属性或者方法。
2、构造函数和实例化对象的区别:
//先 自定义构造函数----->实例化对象
function Person(name,age,sex) {
this.name=name;
this.age=age;
this.sex=sex;
this.eat=function () {
console.log("吃大蒜拌臭豆腐加榴莲酱");
};
}
//再 构造函数---->创建对象
var per=new Person("小苏",38,"女");
// per.eat();//吃
//实例对象是通过构造函数来创建(重点)
//实例对象会指向自己的构造函数(暂时理解,是错误的)
//dir是把这个对象的结构显示出来
console.dir(per);//实例对象
console.dir(Person);//构造函数
//实例对象的构造器(构造函数)
//实例对象的构造器是指向Person的,结果是true,
// 所以,这个实例对象per就是通过Person来创建的
console.log(per.constructor==Person);//结果是true
console.log(per.__proto__.constructor==Person);//结果是true
console.log(per.__proto__.constructor==Person.prototype.constructor);//结果是true
//构造函数
function Animal(name) {
this.name=name;
}
//实例对象
var dog=new Animal("大黄");
console.dir(dog);//实例对象
console.dir(Animal);//构造函数的名字
console.log(dog.__proto__.constructor==Person);//false
console.log(dog.__proto__.constructor==Animal);//true
//判断这个对象是不是这种数据类型(有两种方式)
console.log(dog.constructor==Person);//false
console.log(dog.constructor==Animal);//true
console.log(dog instanceof Person);//false
总结:
实例对象和构造函数之间的关系:
1. 实例对象是通过构造函数来创建的---创建的过程叫实例化
2.如何判断对象是不是这个数据类型?
1) 通过构造器的方式 实例对象.构造器==构造函数名字
2) 对象 instanceof 构造函数名字
尽可能的使用第二种方式来识别,为什么?原型讲完再说
二、设置和获取属性的另一种写法
设置和获取属性前面用的是点语法。其实还可以用中括号,中括号里双引号。大多数时候,和点语法功能一样。后面json对象遍历的时候有不同的地方。
obj.name="Bella" 等于 obj["name]="Bella"
obj.eat() 等于 obj ["eat“”] ()
三、Json格式的数据及遍历
对象:有属性和方法,特指的某个事物。是一组无序属性的集合的键值对,属性的值可以是任意的类型。
JSON格式的数据:一般都是成对的,是键值对。也是一个对象,数据都是成对的,一般JSON格式的数据无论是键还是值都用双引号括起来。
var json = {
"name": "小明",
"age": "10",
"sex": "男" };
区别:var obj={ name:"小明" };属性名没有双引号。
遍历:遍历对象,是不能通过for循环遍历,因为对象是无序的。
可以使用for-in循环遍历。
for(var key in json){
console.log(key); //显示json对象中的属性的名字
console.log(json[key]); //显示json对象中的属性的值
//console.log(json.key); 不能用.key:这会json对象中添加key这个属性。
}
解析:
json是这个对象。key是一个变量,这个变量中存储的是该对象的所有 的属性的名字。
这里的遍历循环不能用点语法。属性中没有key属性,key只是一个变量,用于存储循环过程中该对象属性的名字,
如果使用了点语法,相当于,给对象加上了一个属性名为“key”的属性。
如果使用中括号语法就是 显示json对象中的属性的名字。所以可以使用中括号语法。
点语法和中括号语法区别:
对象中确实有这个属性:对象.属性名字 或者对象[属性名字]
如果对象没有这个属性,只能对象[属性名字]
四、js里面的数据类型
1、原始数据类型: number,string,boolean,undefined, null,object
其中基本类型(简单类型),(值类型): number,string,boolean
复杂类型(引用类型):object
空类型:undefined,null
2、存储位置的区别:
值类型的值在哪一块空间中存储? ---栈中存储
引用类型的值在哪一块空间中存储?---对象在堆上存储,地址在栈上存储
传递方式的区别:
值类型(基本类型)之间传递的是 值
引用类型(对象)之间传递的是 地址(引用)
值类型作为函数的参数,传递的是 值
引用类型作为函数的参数,传递的是 地址
var num=10;
var num2=num;//传递的值
function f1(x) {
x=100;
}
var num=10;
f1(num);
console.log(num);//得到10
var obj={
name:"小明"
};
function f2(obj2) {
obj2.name="小红";
}
console.log(obj.name);//得到小明
f2(obj);
console.log(obj.name);//得到小红
不懂可以看视频,《19简单类型和复杂类型》
五、 js学习中的三种对象
内置对象----js系统自带的对象。 如 Math、 Date 、 String 、 Array、 Object
自定义对象---自己定义的构造函数创建的对象。
浏览器对象---BOM的时候讲。
对象又分为两种:
- 实例对象:通过构造函数创建出来,实例化的对象。
- 静态对象:不需要创建,直接就是一个对象、方法(静态方法)。
实例方法必须通过实例化对象调用,静态方法必须通过大写的对象调用。
1、Math
是一个内置对象, 它具有数学常数和函数的属性和方法。不是一个函数对象。
Math - JavaScript | MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math#₩ママ│ᄚ
Math.PI----π Math.E----常数的底数 Math.abs(值)-----绝对值
Math.ceil(值)----向上取整 Math.floor(值)---向下取整
Math.fround(2)--将任意的数字转换为离它最近的单精度浮点数形式的数字。
Math.max(10,1,9,100,200,45,78) Math.min(10,1,9,100,200,45,78)
Math.pow(2,4) Math.sqrt(16) Math.random()
console.log(Math.random()*5)//产生0-4的随机数
console.log(parseInt(Math.random()*5))//产生0-4的随机整数
console.log(parseInt(Math.random()*5)+1)//产生1-5的随机整数
2、实现系统的Math方法--案例
例1:自定义一个对象,实现系统的max方法
<script>
//例子:自己定义一个对象,实现系统的max方法
function MyMath(){
//添加一个方法,getMax是添加的方法,后面在创建实例对象之后可以调用
this.getMax=function(){
//所有数字中的最大值,假设最大值是arguments[0],后面依次与他比较
var max=arguments[0];
for(var i=0;i<arguments.length;i++){
if (max<arguments[i]){
max=arguments[i];
}
}
return max;
}
}
//实例化一个对象
var mt=new MyMath();
// 调用这个对象的方法,并传入实参
// 因为要获取到这个值,把它传到一个变量中
var result= mt.getMax(10,2,33,42,14,23);
console.log(result);
</script>
例2:随机产生一个十六进制的颜色值,封装成一个函数
// 随机产生一个十六进制的颜色值,封装成一个函数
function getColor(){
// 十六进制颜色值是字符串,前缀带有#
var str ="#";
// 定义一个十六进制的值得数组
var arr=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
for(var i =0;i<6;i++){
// 上面的i是十六进制数的位数,六位数
// 再定义变量num:
// 产生随机数,这个随机数是个索引,根据索引找到数组中对应的值。
// 找到数组中随机的六个数,再和#拼接成为一个十六进制数
var num=parseInt(Math.random()*16);
str+=arr[num];
}
return str;
}
// 调用
console.log(getColor());
这个例子我试过不用forEach()。
视频老师将这段js应用在一个变背景色的例子上了,用到了:
//页面记载的事件
window.onload = function () {
//在文档中通过id属性的值查找这个元素(标签).设置该标签的背景颜色
document.getElementById("dv").style.backgroundColor = getColor();
};
3、Date
语法:
new Date();----
获取当前服务器时间。
new Date(value);
new Date(dateString);---Date括号里可以写入字符串
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);注意参数monthIndex
是从“0”开始计算的,这就意味着一月份为“0”,十二月份为“11”。
(1)获取当前时间-当前服务器时间:
var dt=new Date();
console.log(dt);
//=>Wed Mar 18 2020 10:30:31 GMT+0800 (中国标准时间)
(2) Date括号里可以写入字符串:
var dt=new Date("2017-08-08");
console.log(dt);
//=>Tue Aug 08 2017 08:00:00 GMT+0800 (中国标准时间)
(3) Date.now()--获取的是从1970年1月1日00:00:00 的毫秒数。
var dt=Date.now();
console.log(dt);//毫秒
(4)Date的方法-获取年、月、日、时、分、秒、星期
var dt = new Date();
//获取年份
console.log(dt.getFullYear());
//获取月份
console.log(dt.getMonth()+1);//是0开始的 真实的月份是需要加1的
//获取日期
console.log(dt.getDate());
//获取小时
console.log(dt.getHours());
//获取分钟
console.log(dt.getMinutes());
//获取秒
console.log(dt.getSeconds());
//获取星期
console.log(dt.getDay());//星期从0开始的
注意:日期的日是getDate(),星期几是getDay()。
(5)Date.toDateString()、Date.toLocaleDateString()、Date.toTimeString()、Date.toLocaleTimeString()、Date.valueOf()
var dt=new Date();
console.log(dt.toDateString());//英文的---日期
console.log(dt.toLocaleDateString());//数字格式--日期
console.log(dt.toTimeString());//小时分钟秒
console.log(dt.toLocaleTimeString());//小时分钟秒
console.log(dt.valueOf());//毫秒值
/*结果:
Wed Mar 18 2020
2020/3/18
10:53:38 GMT+0800 (中国标准时间)
上午10:53:38
1584500018709
*/
疑问:
Date是一个内置对象,是静态的,前面讲过,静态对象直接调用,不需要new啊?为什么上面的例子却是new Date().
解决:我尝试了不用赋值,直接Date()和Data.now(),确实不用赋值给一个变量也可以,但是像是getFullYear()、getDate()这这些需要把new Date()给一个新变量。用这个变量.getFullYear()。通过查询MDN手册我发现这些对象前面都有个单词“
prototype-子对象”。所以对于子对象,需要这样new一下。
(
Date.now()
是静态方法。其实大多数都是实例化方法。后面的string、array同理)
例子:格式化一个时间。
答案一是我自己写的错误版本:
function getDate(){
//实例化一个Date对象,获取当前时间
var dt=new Date();
//分别获取年月日时分秒
var year=dt.getFullYear();
var month=dt.getMonth()+1;
var day=dt.getDate();
var hour=dt.getHours();
var minute=dt.getMinutes();
var second=dt.getSeconds();
//返回值如下
return year+"年"+month+"月"+day+"日"+hour+"时"+minute+"分"+second+"秒";
}
//问题重点来了。函数调用:
var dt1=new getDate();
console.log(dt1);
错误版本得不到东西。==》分析原因:
调用的时候我是实例化原来一个我自己定义的函数的对象dt1.。然后输出。问题在于 输出的是一个变量。它能有啥值?
实参都没有。它怎么知道我要格式化哪个日期??
答案二是我老师写的标准版本:
//老师写的标准版本
function getDate(dt){
// var dt=new Date();
//分别获取年月日时分秒
var year=dt.getFullYear();
var month=dt.getMonth()+1;
var day=dt.getDate();
var hour=dt.getHours();
var minute=dt.getMinutes();
var second=dt.getSeconds();
return year+"年"+month+"月"+day+"日"+hour+"时"+minute+"分"+second+"秒";
}
var dt=new Date();
console.log(getDate(dt));
解释:在function getDate()的里就传入一个形参dt,后面实例化变量的时候用到的就是这个dt对象。
(我尝试把形参dt删掉,依然得到结果。接着把实例化的dt全换成this,报错没有getFullYear等函数,所以,还是加上dt吧)
接下来的调用:实例化一个Date ==》调用自定义的函数,传入dt(相当于传入实参了)。
答案三:根据老师的版本,我改正了我之前错误版本的问题:当然还是以老师版本为准,这里只是改正问题。
function getDateTime(){
var dt=new Date();
//分别获取年月日时分秒
var year=dt.getFullYear();
var month=dt.getMonth()+1;
var day=dt.getDate();
var hour=dt.getHours();
var minute=dt.getMinutes();
var second=dt.getSeconds();
return year+"年"+month+"月"+day+"日"+hour+"时"+minute+"分"+second+"秒";
}
var dt1=new getDateTime();
console.log(getDateTime(dt1));
修改的点是调用部分。相对老师版本有点啰嗦了。函数部分依然实例化Date,形成dt变量。调用的时候重新实例化自定义的对象。然后再调用自定义对象,传入dt1。此时的dt1不是空的。因为在getDateTime()里面已经有了dt这个实例化的Date对象了(有了当前的时间)。还有点注意:自己写的函数最后是ruturn 结果,不是console.log结果。
补充:这里时间的显示有个小问题,很多时候时间小于10的数字,会在前面添零。如2020.03.08。这里加入一个判断即可。
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
hour = hour < 10 ? "0" + hour : hour;
minute = minute < 10 ? "0" + minute : minute;
second = second < 10 ? "0" + second : second;
以上就是格式化一个时间的脚本,可以单独封装到一个文件里。以后直接使用
<script src="***.js"></script>直接调用。
4、String 及下面的方法
String字符串是一个对象。可看成字符组成的数组,但js中没有字符类型。字符是一个一个的,在别的语言中字符用一对单引号括起来。在js中字符串可以使用单引号也可以使用双引号。因为字符串可以看成是数组,所以可以通过for循环进行遍历。
字符串特性:不可变性,字符串的值是不能改变。 字符串的值之所以看起来是改变的,那是因为指向改变了,并不是真的值改变了
String对象下的方法
实例方法---->必须要通过new的方式创建的对象(实例对象)来调用的方法。
静态方法---->直接通过大写的构造函数的名字调用的方法(直接通过大写的对象名字调用的),如Math。
字符串很常用属性:
* .length------>字符串的长度
* .charAt(索引);----->取字符串中第几个值,返回值是指定索引位置的字符串,超出索引,结果是空字符串。
var str="whatareyounoshalei"; var result=str.charAt(10); console.log(result);
* .fromCharCode(数字值,可以是多个参数);---->返回的是ASCII码对应的值。
//fromCharCode()是静态方法,直接通过String调用 var str=String.fromCharCode(107,108,109); console.log(str);//=>klm 当多个参数时,返回的是一个字符串。
* .concat("字符串1","字符串2",...);--->拼接。
将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。
concat
方法并不影响原字符串。var str="bella"; console.log(str.concat("你好","么"))
* .indexOf(要找的字符串,[从某个位置开始的索引]);->返回的是这个字符串的索引值,没找到则返回-1。
var str="京东真的好厉好害啊"; var index1=str.indexOf("好");//返回第一个"好"的索引 var index2=str.indexOf("好",5);//从索引5开始寻找“好” console.log(index1);//=>4 console.log(index2);//=>6
* .lastIndexOf(要找的字符串);--->从后向前找,但是索引仍然是从左向右的方式,找不到则返回-1
* .replace("原来的字符串","新的字符串");--->用来替换字符串的
var str="小苏好帅哦,真的好勇敢哦"; // 可以先用 indexOf 判断有没有"帅"字 if(str.indexOf("小苏")!=-1){ str=str.replace("小苏","宋威龙"); }else{ console.log("不存在"); } console.log(str);
* .slice(开始的索引,结束的索引);从索引5的位置开始提取,到索引为10的前一个结束,没有10,并返回这个提取后的字符串
var str = "如果有一天我回头了,请记住,我曾径用心了"; //从索引5的位置开始提取,到索引为10的前一个结束,没有10,并返回这个提取后的字符串 str = str.slice(5, 10); console.log(str);
* .split("中间间隔的字符串(这个字符串会消失)",切割后留下的个数);--->切割字符串,这里很多时候要用循环。
下面两个例子结果一样么?
var str="你好啊|我是|Bella"; var arr=str.split("|"); console.log(arr); // =>["你好啊", "我是", "Bella"] var str="乔峰|慕容|凤姐|梅超风|小苏"; var arr=str.split("|"); for(var i=0;i<arr.length;i++){ console.log(arr[i]); }//得到一个数组
* .substr(开始的位置,新字符串的个数);--->返回的是截取后的新的字符串。
注意slice(开始的索引,结束的索引)的区分
* .substring(开始的索引,结束的索引);--->返回截取后的字符串,不包含结束的索引的字符串。
var str="你好,我是bella"; var arr1=str.substr(3,2); var arr2=str.substring(3,4); console.log(arr1);//=>我是 console.log(arr2);//=>我
var str="你好,我是bella"; str.substr(3,5); console.log(str); // 注意:这里犯下错误。得到“你好,我是bella”,字符串没有变化,原因是前面提到过的 // 字符串原本的值没有改变,要想获取到新字符串的值,需要把它重新赋值给新的字符串
* .toLocaleLowerCase();--->转小写
* .toLowerCase();--->转小写
* .toLocaleUpperCase()转大写
* .toUpperCase();转大写
* .trim();去掉字符串两端的空格。
5、字符串案例
例1:取出字符串中的某个值。
var str="今天是星期四,还有三天我就要上班了";
// 首先利用indexOf()函数,判断“星期四”这个值的索引
var index=str.indexOf("星期四");
// 再利用substr()函数取值
str =str.substr(index,3);
console.log(str);
要想变得更灵活,实现交互式:
var str="今天是星期四,还有三天我就要上班了";
var key="星期四"//后期这里可以写“请输入查询的值”
var index=str.indexOf(key);
str =str.substr(index,3);
console.log(str);
例2:找到这个字符串中所有“o”的位置。
var str2 = "hello wod odd ott fbo nhyo";
var index = 0;//开始的位置
var key = "o";//要找的字符串
while ((index = str2.indexOf(key, index)) != -1) {//如果是-1情况,说明找完了
console.log(index);
index += key.length;
}
//4 7 10 14 20 25
//var index=str2.indexOf("o",0);
//console.log(index);
// ----------------我的答案----------------------------
//1、去重的自定义函数uniq()
function uniq(array){
var temp = []; //一个新的临时数组
for(var i = 0; i < array.length; i++){
if(temp.indexOf(array[i]) == -1){
temp.push(array[i]);
}
}
return temp;
}
// 2、
var str2="hello wod odd ott fbo nhyo";
// debugger;
var arr=[];//
for(var i=0;i<str2.length-1;i++){
var index=str2.indexOf("o",i);
if(index!=-1){
arr[i]=index;
}
}
console.log(uniq(arr));
上面有老师版本和我的版本。都能得到正解,我的是有点小插曲,进行以下归纳:
老师的比我的高明之一在于:我的是从索引零开始挨个寻找,老师是找到第一个目标之后, 从这个直接获取目标的长度,跨过这个长度之后再继续寻找。
高明之二在于:老师把目标字符放在变量里,这样用起来更灵活。
我的版本可以存储结果,因为我放在了数组里面。
我的问题在于:4、7、10...答案是对的。但是重复输出了。
解决:循环出现问题,发现错误的规律是4输出5个,7输出3个...正好是从寻找的源头开始 第五个数是"o",第三个数是"o",第三个数是"o",第四个数是"o",第六个数是"o"... 即在第几个找到了"o",就重复输出几次。 本来想修改循环的,解决重复输出问题,但不知道怎么解决,
最终使用的去重的方法。
例3:找到这个字符串中每个字符串出现了多少次
解决思路:如下图一hello为例,我们想得到的是:h出现几次,e出现几次,l出现几次,o出现几次。
首先建立一个空对象,把每个字母作为键,字母出现的次数作为值,添加到对象中遍历。
补充一个知识点:
判断一个对象里有没有“name”属性:就把对象["属性名字"]放到if的括号里判断。(我之前有个错误:if括号里面的方括号里面属性名没有加引号,就显示没有这个属性,这是错误的。应该加引号)
var obj={
"name":"男"
}
if(obj["name"]){
console.log("有")
}else{
console.log("没有")
}
var str3 = "whatOareYyouYnoYshaHleiHoHmyHgod";
//第一步:把所有的字母全部变成小写
str3 = str3.toLocaleLowerCase();
//第二步:创建一个空对象,存放拆分的新字符们,拆分目的:把字母作为键,次数作为值
var obj = {};
//第三步,遍历字符串,获取每个字母
for (var i = 0; i < str3.length; i++) {
// 现在需要判断obj这个新对象里有没有这个字母,有的话数量加1,没有的话添加这个键,并初始数量为1
var key = str3[i];//获取遍历的每个字母
if (obj[key]) {//判断obj中有没有这个键
//对象中有这个字母了
obj[key]++;
} else {
//对象中没有这个字母,那就把字母加到对象中,并且给这个字母一个出现的次数,默认1次
obj[key] = 1;
}
}
//遍历obj对象,显示每个字母的次数
for(var key in obj){
console.log(key+"这个字母出现了"+obj[key]+"次");
}
扩展例4:翻译英语单词(训练键值对的获取)
var obj={
"abandonment":"n.放弃",
"abbreviation" :"n.缩写",
"abeyance" :"n.缓办,中止",
"abide" :"v.遵守",
"ability" :"n.能力",
"able" :"adj.有能力的,能干的",
"abnormal": "adj.反常的,变态的",
"aboard": "adv.船(车)上",
"abolish" :"v.废除,取消",
"abolition" :"n.废除,取消"
};
var str=prompt("请输入单词");
if(obj[str]){
console.log(obj[str]);
}else{
console.log("不能存在");
}
扩展例5:简繁体转换(训练键值对的获取)
// 简繁体转换(见备注资料)
var arr = ["你=伱", "说=詤", "我=莪", "好=恏", "帅=帅", "气=气", "的=的", "杨=楊", "哥=哥"];
//做一个字典:键和值的关系 键:简体的中文,值:对应的繁体中文
var obj={};
//遍历数组获取数组中每一个字符串内容
for (var i = 0; i < arr.length; i++) {
//console.log(arr[i]);//你=伱
var keyWords=arr[i].split("=");//keyWords-->是数组["好","恏"]
//keyWords[0]---键 keyWords[1]---值
obj[keyWords[0]]=keyWords[1];
//console.log(keyWords);
}
var result="";//把简体对应的所有的繁体字保存起来
//提示用户输入中文
var str=prompt("请输入中文");//你说我帅不 啥?
//遍历用户输入的字符串
for(var i=0;i<str.length;i++){
//判断用户输入的每个字在键值对中是否存在
if(obj[str[i]]){
//有这个简体字对应的繁体字的
result+=obj[str[i]];
}else{
//没有文字对应的繁体字
result+=str[i];
}
}
console.log(result);
6、array对象及其方法
创建对象的两种方式:
- 构造函数 var arr1=new Array();
- 字面量的方式 var arr2=[];
(只要是数组就是对象)
array对象下的方法
-
Array.isArray(对象)---->判断这个对象是不是数组。(静态方法)
还有种方法是使用关键字 instanceof
var arr={};
var arr1=[];
// 使用的方式Array.isArray()
console.log(Array.isArray(arr));
// 使用关键字instanceof
console.log(arr1 instanceof Array);
-
concat()-->拼接数组
语法:数组1.concat(数组2,数组三...)
var arr1=[10,20,30];
var arr2=[40,50,60];
console.log(arr2.concat(arr1,arr2));
-
every-->在括号里传入一个参数,这个参数是函数。每个元素都需通过这个函数的测试。返回布尔类型值。
(函数可以作为参数使用)(tips:以后看到手册里callback的参数,就是这里要放一个函数)
语法:
var arr=[1000,2000,3300];
arr.every(function(element,index,array){
})
function是用来测试每个元素的函数,它可以接收三个参数:
element--
用于测试的当前值。
index
可选--用于测试的当前值的索引。
array
可选--调用 every
的当前数组。--现在这里就是arr数组。
{这个从手册复制过来的,啥意思}thisArg--
执行 callback
时使用的 this
值。
返回值:布尔类型数据-如果回调函数的每一次返回都为 true 值,返回 true
,否则返回 false
。
这个方法可以用来【筛选】。看每个元素是不是都满足某个条件。
var arr=["小白","小黑","小红","小兰"];
arr.every(function (ele,index) {
console.log(ele.length>4);
})
tips:以后看到function()怎么知道function这里需要几个参数,代表意义是什么?见https://blog.csdn.net/bellediao/article/details/104994438
-
filter()-有一个数组,传入一个函数测试数组中的元素,最后返回满足测试条件的元素,把他们放到新的数组中。
var arr=[10,,0,20,30,0,50,0,70,0];
var newArr=arr.filter(function (ele,index) {
return ele>0;
})
console.log(newArr);//=>10, 20, 30, 50, 70
-
push(值)-把值追加的数组中,返回值是追加数据后的长度。
-
pop()--删除数组中最后一个值,返回值就是数组中最后一个值。
-
shift--删除数组中第一个值,返回值就是删除的值。
-
unshift--向数组中第一个元素前面插入一个元素,返回值是插入数据后的长度。
这四个方法很重要。下面是实例:
var arr=[10,20,30];
arr.push(40,50);
console.log(arr);//=>10, 20, 30, 40, 50
var arr2=arr.pop();
console.log(arr);//删除最后一个值之后为10, 20, 30, 40
console.log(arr2);//删除的值是50
var arr3=[10,20,30];
var arr4=arr3.shift();
console.log(arr3);//删除第一个值之后为20, 30
console.log(arr4);//删除的值是10
var arr=[10,20,30];
arr.unshift(100);
console.log(arr);//把100添加到数组中:100, 10, 20, 30
-
forEach(function())--用于遍历数组,相当于for循环
(蜜汁官方解释:按升序为数组中含有效值的每一项执行一次 callback
函数)
语法:
var arr =[10,20,30,40];
arr.forEach(function (element [,index] [,array]) {
})
// 依次把items中的元素加入copy数组中。
const items = ['item1', 'item2', 'item3'];
const copy = [];
// 以前用for循环
for (let i=0; i<items.length; i++) {
copy.push(items[i]);
}
// 现在用forEach
items.forEach(function(item){
copy.push(item);
});
只要条件允许,也可以使用 filter()
提前过滤出需要遍历的部分,再用 forEach()
处理。
tips:怎么看这个方法是不是用低版本浏览器?见https://blog.csdn.net/bellediao/article/details/104994373
- 不适用ie8,怎么解决?(在mdn文档里面 找到这个单词---Polyfill--兼容旧环境)
可以在你调用 forEach()
之前插入下面的代码或者引入含有这个代码的文件,在本地不支持的情况下使用 forEach()
。
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
// 1. Let O be the result of calling toObject() passing the
// |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get() internal
// method of O with the argument "length".
// 3. Let len be toUint32(lenValue).
var len = O.length >>> 0;
// 4. If isCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let
// T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty
// internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
-
indexOf(元素值)--寻找数组中该值所在的索引
var arr=[10,20,30];
var index= arr.indexOf(30);
var index1= arr.indexOf(100);
console.log(index);//=>2
console.log(index1);//=>-1 不存在返回-1
-
join("字符串")--数组元素中间都加某个字符串,返回的是字符串
var arr=["小白","小黑","小红","小芳","小绿","小苏"];
var str=arr.join("|");
console.log(str);
//=>小白|小黑|小红|小芳|小绿|小苏
-
map(函数)--数组中每个元素都要执行这个函数,把执行之后的结果重新、全部放在一个新的数组中。
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
console.log(roots);
-
reverse()--翻转数组
var arr=[10,20,30];
arr.reverse();
console.log(arr);
-
sort()--排序
var arr=[10,40,30,20];
arr.sort();
console.log(arr);
但是,sort()这个方法极其不稳定,解决方法是:里面传入一个函数。语法如下:
var arr = [10, 40, 30, 100];
arr.sort(function compare(a, b) {
// 这里的a相当于arr[j]
// 这里的b相当于arr[j+1]
if (a < b) { // 按某种排序标准进行比较, a小于b,返回-1
return -1;
}
if (a > b) {
return 1;
}
// a等于b,返回0
return 0;
});
console.log(arr);
-
slice(开始的索引,结束的索引)--把截取的数组数值放在新数组中,但不包括结束的索引对应值。
var arr=[10,20,30,40,50,60,70,80,90,100];
var newArr= arr.slice(3,7);
console.log(newArr);
-
splice(开始位置的索引,要删除元素的个数,替换元素的值)--一般用于删除数组中某个元素,或替换元素,或在某个位置添加元素。
(1)在某个位置添加元素
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
myFish.splice(2, 0, 'drum');
// 2-索引为2;0-不删任何值;'drum'-在索引为2的位置插入'drum'
console.log(myFish);
// =》 "angel", "clown", "drum", "mandarin", "sturgeon"
(2)删除某元素
var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
myFish.splice(2, 1);
// 从索引为2的位置删除一项(也就是'drum'这一项)
console.log(myFish);
// =》"angel", "clown", "sturgeon"
六、基本包装类型
普通变量不能直接调用属性或者方法, 对象可以直接调用属性和方法。
基本包装类型:本身是基本类型,但是在执行代码的过程中,如果这种类型的变量调用了属性或方法,
那么这种类型就不再是基本类型了,而是基本包装类型,这个变量也不是普通的变量了,而是基本包装类型对象。
string number boolean是普通类型,也可能是基本包装类型。
用下面的例子讲解:
var str="hello";//此时,str是普通变量
str=str.replace("ll","HH");//str在这里调用了replace方法,它就是基本包装类型。
console.log(str);
var flag=new Boolean(false);//flag本来是变量,new之后就是对象了。它里面放了boolean类型的false。
var result=true&&flag;//这里它返回的是flag这个对象
console.log(result);//=》Boolean {false}
//但如果这样写:
var result=flag&&true;//这里它返回的是true。
console.log(result);//=》true
规律: 如果是一个对象&&true,那么结果是true,
如果是一个true&&对象,那么结果是对象。
var num=10;//普通变量
var num2=Number("10");//Number是类型转换,没有new就不是对象
var num3=new Number("10");//new 了之后变成对象,是基本包装类型
总结:以第一个例子为例:
str虽然是普通变量,只要它调用方法了,系统就自动执行了new。就变成了对象。
--------------------------------------------------------------------------------------------------------------------
作业:
* 所有的案例一遍:
* Math对象的案例
* 格式化的日期的案例
* string中的案例
* 将一个字符串数组输出为|分割的形式,比如“刘备|张飞|关羽”。使用两种方式实现
*将一个字符串数组的元素的顺序进行反转。["a", "b", "c", "d"] -> [ "d","c","b","a"]。使用两种种方式实现。提示:第i个和第length-i-1个进行交换
*工资的数组[1500, 1200, 2000, 2100, 1800],把工资超过2000的删除
* ["c", "a", "z", "a", "x", "a"]找到数组中每一个a出现的位置
* 编写一个方法去掉一个数组的重复元素
* Math和Date和String和Array中的所有的方法,全部一遍
--------------------------------------------------------------------------------------------------------
小建议:
* Ctrl+鼠标左键--转到定义--适合没有网络,自己写代码,看结果,总结
* MDN--在线文档,查结果--初级学习
* 百度--一定要多查--对比的看
* 谷歌--百度没有的,去谷歌--多对比
-------------------------
JavaScript数组去重(12种方法,史上最全) - 前端开发随笔 - SegmentFault 思否 https://segmentfault.com/a/1190000016418021
--------------------------------------------------------------------------------------------------------------------------------