JavaScript基础(上)数据类型、表达式和运算符、语句、对

2018-08-15  本文已影响6人  左左4143

数据类型

课程大纲

  1. 数据类型
  2. 表达式和运算符
  3. 语句
  4. 对象
  5. 数组
  6. 函数
  7. this
  8. 闭包和作用域
  9. OOP
  10. 正则与匹配模式

数据类型

隐式转换

//巧用加减号 
var x = "37" - 7;
console.log(x);//输出30

var y = "37" + 7;
console.log(y);//输出377

//等于与严格等于
console.log("1.23"==1.23);//true;

var a = 1;
var b = "1";
console.log(a==b);//true;
console.log(a===b);//fales,会先判断类型;

var str = "string";
console.log(str.length);//输出 6

str.t = 3;
console.log(str.t);//输出undefined
//访问基础类型变量的属性时会将基础类型临时变换为对象类型 完成访问后临时对象会被销毁 所以str.t是没有值得

//类型检测
//typeof  适合基本类型及function检测 遇到null失效
console.log(typeof(100));//输出number
console.log(typeof("string"));//输出strin

//instanceof 适合自定义对象 也可以用来检测原生对象 在不同iframe和window间检测时失效
var b1 = [1,2] instanceof Array === true;
console.log(b1);//true

var b2 = new Object() instanceof Array === true;
console.log(b2);//false

//Object.prototype 通过{}.toString 拿到 适合内置对象和基本类型 遇到null 和undefined时失效(IE 6 7 8 返回[object Object])
console.log(Object.prototype.toString.apply([]));//输出 [object Array]
console.log(Object.prototype.toString.apply(function(){}));//输出[object Function]

表达式和运算符

//原始表达式 常亮、直接量、关键字、变量
3.14;  "test"; null; this; true; i; j; k;

//复合表达式
10*20;

//数组,对象初始化表达式
[1,2];  new Array(1,2);//等价
[1,,,4]; [1,undefined,undefined,4];//等价
var a = {x:1,y:2};    var b = new Object(); b.x = 1; b.y = 2;//等价

//函数表达式
var fe = function(){};
(function(){console.log("hello world");}());

//属性访问表达式
var o = {x:1};
o.x;
o['x'];

//调用表达式
func();

//对象创建表达式
new Func(1,2);
new Object;

//运算符

//三元运算符
var val = 1>2?"NO":"YES";

//逗号运算符
var val2 = (1,2,3);//val = 3;

//delete 运算符
var obj = {x:1};
console.log(obj.x);//1
delete obj.x;
console.log(obj.x);//undefined



语句

//块  block
{
    var str = "hi";
    console.log(str);
}

// {a:1,b:2}//SyntaxError:Unexpected token:
var o = {a:1,b:2}//ok

//注意 没有块级作用域 下边这两种代码是一个效果
for (var i = 0; i < 3; i++){
    var str = "hi1";
    console.log(str);
}
console.log(i);//输出3

var j = 0
for(;j < 3; j++){
    var str = "hi2";
    console.log(str);
}
console.log(j);//输出3

//函数作用域
function foo(){
    var a = 1;
    console.log(a);//1
}
foo();
console.log(typeof a);//undefined

// var
function foo2() {
    var a = b = 1;//这种写法 a 成为局部变量外部不能访问 b成为全局变量
}
foo2();
console.log(typeof a);//undefined
console.log(typeof b);//number

//声明多个变量的正确写法
var a = 1,  b = 1;

//try catch语句
/*
try{
    throw new Error("oops");
}catch(ex) {
    console.log(ex);
}

try{
    throw new Error("oops2");
} finally {
    console.log("finally");
}

try{
    throw "test";
} catch(ex) {
    console.log(ex);
} finally {
    console.log('finally2');
}
*/

//function 语句

//函数声明 函数语句
var f = fd();
console.log(f);//true
function fd(){
    //do sth
    return true;
}

//fe();//TypeError 异常
//函数表达式
var fe = function(){
    //do sth
};

//在函数声明前调用函数可以成功 但是函数表达式前调用不可以

//for...in 遍历的顺序不确定
var p;
var obj = {x:1,y:2,z:3};
for (p in obj) {
    console.log(typeof p +"\n"+ p);
}


//with 语句 可以修改作用域 现在已经不建议使用
with({x:1}){
    console.log(x);
}
/* 浏览器中
with(document.forms[0]){
    console.log(name.value);
}
*/

//严格模式
/**
 * 严格模式是一种特殊的执行模式,它修复了部分语言上的不足,提供更强的错误检查,并增强安全性
 */

'use strict';//放在方法内部或者js文件开头

//严格模式不允许使用with 会报错

对象

//创建对象
var obj1 = {x:1,y:2};

//嵌套
var obj2 = {
    x:1,
    y:2,
    o:{
        z:3,
        n:4
    }
}

//原型链
function foo(){};
foo.prototype.z = 3;

var obj = new foo();
obj.x = 2;
obj.y = 1;

obj.z//3;
typeof obj.toString;//'function'
'z' in obj;//true
obj.hasOwnProperty('z');//false

//访问对象中不存在的属性会在原型链上向上查找, 但赋值对象中不存在的属性时只会在对象上生成一个新属性
obj.z = 5;
obj.hasOwnProperty('z');//true
foo.prototype.z//仍然是3
obj.z;//5

// delete 只能删除对象本身的属性不能删除原型链上的属性


var obj3 = Object.create({x:1});
obj.x;//1
typeof obj3.toString//'function'
obj3.hasOwnProperty('x');//false

var obj4 = Object.create(null);
obj4.toString;//undefined


//对象的属性操作

var obj5 = {x:1,y:2};
obj5.x;//1
obj5["y"];//2

obj5["x"] = 3;
obj5.y = 4;

obj5.z;//undefined


//异常
var obj6 = {x:1};
obj6.y;//undefined
var yz = obj.y.z;//TypeError
obj.y.z = 2;//TypeError

var yz;
if(obj6.y){
    yz = obj.y.z;
}

//或者
var yz = obj6 && obj6.y && obj6.y.z;

//属性删除
var person = {age:8,title:"fe"};
delete person.age;//true
delete person["title"];//true
person.age;//undefined
delete person.age;//true//虽然已删除 但现在对象中已经没有这个属性,所以返回true

delete Object.prototype;//false

var descriptor = Object.getOwnPropertyDescriptor(Object,'prototype');
descriptor.configurable;//false

var globalVal = 1;
delete globalVal;//false

(function(){
    var localVal = 1;
    return delete localVal;
}());//false

function fd(){
    delete fd;//false
}

(function(){
    function fd(){
        return delete fd;
    }
}());//false

//属性检测
var cat = new Object;
cat.legs = 4;
cat.name = "Kitty";

"legs" in  cat;//true
"abc" in cat;//false
"toString" in cat;//true

cat.hasOwnProperty("legs");//true
cat.hasOwnProperty("abc");//false
cat.hasOwnProperty("toString");//false 对象上没有 原型链上才会有

cat.propertyIsEnumerable("legs");//true 属性是否可枚举
cat.propertyIsEnumerable("toString");//false


Object.defineProperty(cat,"price",{enumerable:false,value:1000});//生成一个不可枚举的属性
console.log(cat.propertyIsEnumerable("price"));//false
console.log(cat.hasOwnProperty("price"));//true

//属性赋值判断
if(cat && cat.legs){
    cat.legs *= 2;
}

if(cat.legs != undefined) {
    // 相当于 !==undefined or !== null 因为不是严格模式 undefinded 相当于null
}

if(cat.legs !== undefined) {
    //严格模式 只判断undefined
}

//属性枚举
var o = {x:1,y:2,z:3};
"toString" in o;//true
o.propertyIsEnumerable('toString');//fals
var key;
for(key in o){
    console.log(key);//x,y,z
}

var obj = Object.create(o);
obj.a = 4;
var key1;
for(key1 in obj){
    console.log(key1);//a x y z
}

console.log("\n\n");
// 过滤原型链上的属性
var obj2 = Object.create(o);
obj2.a = 5;
var key2;
for(key2 in obj2){
    if(obj2.hasOwnProperty(key2)){
        console.log(key);
    }
}


//set/get方法
var man = {
    name:'Bosn',
    weibo:'@Bosn',
    get age(){
        return new Date().getFullYear()-1988;
    },
    set age (val){
        console.log('Age can\'t be to ' + val);
    }
};

console.log(man.age);//30
man.age = 100;//Age can't be set to 100
console.log(man.age);//still 30

var woman = {
    weibo:'@Bosn',
    $age:null,
    get age(){
        if(this.$age == undefined) {
            return new Date().getFullYear() - 1988;
        } else {
            return this.$age;
        }
    },
    set age(val){
        val = +val;
        if(!isNaN(val)&&val > 0 && val < 150) {
            this.$age = +val;
        } else {
            throw new Error('Incorrect val ='+val);
        }
    }
};

console.log(woman.age);//30
woman.age = 100;
console.log(woman.age);//100
//woman.age = 'abc';//Error: Incorrect val =NaN

//get/set 与原型链
function foo(){};
Object.defineProperty(foo.prototype,'z',{get:function(){return 1;}});
var obj = new foo();
console.log(obj.z);//1
obj.z = 10;
console.log(obj.z);//仍然是1

Object.defineProperty(obj,'z',{value:100,configurable:true});//configurable 是否可以delete,update属性
console.log(obj.z);//100
delete obj.z;
console.log(obj.z);//变回1

var o ={};
Object.defineProperty(o,'x',{value:1});//writable=false 不可写,configurable=false
var obj = Object.create(o);
console.log(obj.x);//1
obj.x = 100;
console.log(obj.x);//仍然是1 因为属性在原型链上并且不可写

Object.defineProperty(obj,'x',{writable:true,configurable:true,value:100});
console.log(obj.x);//100
obj.x = 200;
console.log(obj.x);//200

/**
 * writable : 是否可写/可修改
 * enumerable:属性是否可以被遍历,枚举,决定这个属性是否会在forin中出现
 * configurable:属性是否可以再次被修改,是否可以通过delete删除属性
 */

//属性标签
console.log(Object.getOwnPropertyDescriptor({pro:true},'pro'));
//打印结果
/**
{ value: true,
  writable: true,
  enumerable: true,
  configurable: true } 
 */

 console.log(Object.getOwnPropertyDescriptor({pro:true},'a'));//undefined

//----------
 var pserson = {};
 Object.defineProperty(pserson,'name',{
     configurable:false,
     writable:false,
     enumerable:true,
     value:'Bosn Ma'
 });
 //Object.defineProperty 接收三个参数 1、被设置属性的对象 2、属性的名字 3、属性标签对象

 console.log(pserson.name);//Bosn Ma
 person.name = 1;
 console.log(pserson.name);//still Bosn Ma 因为writable 为false
 delete pserson.name;//false 因为configurable 为false

//----------

 Object.defineProperty(person,'type',{
     configurable:true,
     writable:true,
     enumerable:false,
     value:"Object"
 });

 console.log(Object.keys(pserson));//打印出['name'],而type没有打印出来 因为enumerable为false

 //定义多个属性 
 Object.defineProperties(person,{
     title:{
         value:"fe",
         enumerable:true
        },
     corp:{
         value:"BABA",
         enumerable:true
        },
     salary:{
         value:50000,
         enumerable:true,
         writable:true
        }
});//不写的属性标签默认为false 或者null

console.log(Object.getOwnPropertyDescriptor(person,'salary'));//{ value: 50000,writable: true,enumerable: true,configurable: false }
console.log(Object.getOwnPropertyDescriptor(person,'corp'));//{ value: 'BABA',writable: false,enumerable: true,configurable: false }

Object.defineProperties(person,{
    title:{value:'fe',enumerable:true},
    corp:{value:'BABA',enumerable:true},
    salary:{value:10000,enumerable:true},
    luck:{
        get:function(){
            return Math.random()>0.5?'good':'bad';
        }
    },

    promote:{
        set:function(level){
            this.salary *= 1 + level * 0.3;
        }
    }

});

console.log(Object.getOwnPropertyDescriptor(pserson,'salary'));//{ value: 5000,writable: false,enumerable: true,configurable: false }
console.log(Object.getOwnPropertyDescriptor(pserson,'corp'));//{ value: 'BABA',writable: false,enumerable: true,configurable: false }
console.log(person.salary);//10000
console.log(pserson.luck);//good
person.promote = 1;
console.log(person.salary);//13000


//对象标签 对象序列化
/**
 * [[proto]]
 * [[class]]
 * [[extensible]]
 */

//[proto] 原型
//Object.prototype
//[class] 类型

var toString = Object.prototype.toString;
function getType(o){
    return toString.call(o).slice(8,-1)
};

console.log(toString.call(null));//'[Object Null]'
console.log(getType(null));//"Null"
console.log(getType(undefined));//"Undefined"
console.log(getType(1));//"Number"
console.log(getType(new Number(1)));//"Number"
console.log(typeof new Number(1));//"object"
console.log(getType(true));//"Boolean"
console.log(getType(new Boolean(true)));//"Boolean"


//extensible 对象是否可扩展
var obj = {x:1,y:2};
console.log(Object.isExtensible(obj));//true
Object.preventExtensions(obj);//阻止对象继续扩展属性
console.log(Object.isExtensible(obj));//false

obj.z = 1;
console.log(obj.z)//undefined 因为对象此时不可扩展
var a = Object.getOwnPropertyDescriptor(obj,'x');
console.log(a);//{ value: 1, writable: true, enumerable: true, configurable: true }
Object.seal(obj);//seal 会将对象上所有的属性的configurable设置为false
var b = Object.getOwnPropertyDescriptor(obj,'x');
console.log(b);//{ value: 1, writable: true, enumerable: true, configurable: false }
console.log(Object.isSealed(obj));//true 判断对象的属性是否被seal

Object.freeze(obj);//freeze 将对象属性设置为不可写
var c = Object.getOwnPropertyDescriptor(obj,'x');
console.log(c);//{ value: 1, writable: false, enumerable: true, configurable: false }
console.log(Object.isFrozen(obj));//true 判断对象的属性是否被freeze

//冻结对象时候并不会影响对象的原型链

//序列化 其他对象方法
var obj = {x:1,y:true,z:[1,2,3],nullVal:null};
var jsonStr = JSON.stringify(obj);
console.log("json字符串:"+jsonStr);//json字符串:{"x":1,"y":true,"z":[1,2,3],"nullVal":null}

obj = {val:undefined,a:NaN,b:Infinity,c:new Date()};//undefined值的属性不会出现序列化字符串中,NaN和Infinity 会变成null
jsonStr = JSON.stringify(obj);
console.log("json字符串2:"+jsonStr);//son字符串2:{"a":null,"b":null,"c":"2018-03-13T08:06:32.183Z"}

//json 数据变为对象
obj = JSON.parse('{"x":1}');
console.log(obj.x);//1

//自定义序列化 在对象属性中设置'toJSON'方法 
var obj = {
    x:1,
    y:2,
    o:{
        o1:1,
        o2:2,
        toJSON:function(){
            return this.o1 + this.o2;
        }
    }
}

var jsonStr = JSON.stringify(obj);
console.log(jsonStr);//{"x":1,"y":2,"o":3}

//toString 和 valueOf
var obj = {x:1,y:2};
console.log(obj.toString());//[object Object]

obj.toString = function(){
    return this.x + this.y;
};
console.log("Result" + obj);//Result3

console.log(+obj);//3 from toString

//valueOf 尝试把对象转换为基本类型的时候回执行的方法 比toString方法优先级高
obj.valueOf = function(){
    return this.x + this.y + 100;
};

console.log(+obj);//103 from valueOf
console.log("Result" + obj);//Result103 因为有valueOf


数组

数组和一般对象的异同

/**
 * JS中的数组是弱类型的,数组中可以含有不同类型的元素,元素甚至可以是对象或其他数组
 */

var arr = [1,true,null,undefined,{x:1},[1,2,3]];//字面量创建方式

console.log(arr[5][1]);

//创建数组的方式
//1. 字面量方法
var BAT = ['Alibaba','Tencent','Baidu'];
var students = [{name:'Bosn',age:27},{name:'Nunnly',age:3}];
var arr = ['Nunnly','is','big','keng','B',123,true,null];
var arrInArr = [[1,2],[3,4,5]];

var commasArr1 = [1,,2];
console.log(commasArr1[1]);//undefined
var commasArr2 = [,,];
console.log(commasArr2[0]);//undefined

//2. Array构造器创建数组 new是可以省略的
var arr = new Array();
var arrWithLength = new Array(100);
var arrLikesLiteral = new Array(true,false,null,1,2,"hi");//等价于[true,false,null,1,2,"hi"]

//数组元素的读写
var arr = [0,1,2,3,4,5];
console.log(arr[1]);//1
console.log(arr.length);//6
console.log(arr);//[0,1,2,3,4,5]

arr[6] = 6;
console.log(arr.length);//7

delete arr[0];//删除第0个元素
console.log(arr.length);//7
console.log(arr);//[ <1 empty item>,1,2,3,4,5,6]
console.log(arr[0]);//undefined

//数组元素的增删 (JS中的数组是动态的 不需要指定大小)
var arr = [];
arr[0] = 1;
arr[1] = 2;
arr.push(3);//在数组尾部添加元素
console.log(arr);//[ 1, 2, 3]

arr[arr.length] = 4;//相当于 arr.push(4);
console.log(arr);//[ 1, 2, 3, 4]

arr.unshift(0);//在数组头部添加元素
console.log(arr);//[ 0, 1, 2, 3, 4]

delete arr[2];
console.log(arr);//[ 0, 1, <1 empty item>, 3, 4 ]
console.log(arr.length);//5

console.log(2 in arr);//false

arr[3] = undefined;
console.log(arr);//[ 0, 1, <1 empty item>, undefined, 4 ]
console.log(3 in arr);//true

arr.length -= 1;
console.log(arr);//[ 0, 1, <1 empty item>, undefined ]第四个元素被删除

arr.pop();//相当于length - 1 将数组尾部的元素删除
console.log(arr);//[ 0, 1, <1 empty item> ] 第三个元素被删除

arr.shift();//删除数组头部的元素
console.log(arr);//[ 1, <1 empty item> ]

//数组迭代
var i = 0, n = 10;
var arr = [1,2,3,4,5];
for(; i < n; i++){
    console.log(arr[i]);//1,2,3,4,5,undefined,undefined,undefined,undefined,undefined
}

for(i in arr) {
    console.log(arr[i]);//1,2,3,4,5
}

//forin是遍历的对象的属性 所以在原型链上加上属性x  也会打印出来

Array.prototype.x = 'inherited';
for(i in arr) {
    console.log(arr[i]);//1,2,3,4,5,inherited
}

//过滤原型链上的属性
for(i in arr) {
    if(arr.hasOwnProperty(i)){
        console.log(arr[i]);//1,2,3,4,5
    }
}

//二维数组 
var arr = [[0,1],[2,3],[4,5]];
var i = 0, j = 0;
var row;
for(;i<arr.length;i++){
    row = arr[i];
    console.log('row' + i);
    for(j=0;j<row.length;j++){
        console.log(row[j]);
 
    }
}
//打印结果 row0 0 1 row1 2 3 row2 4 5

//稀疏数组 (并不含有从0开始的连续索引,一般是length属性值比实际元素个数大) 在实际应用中并不常见
var arr1 = [undefined];
var arr2 = new Array(1);
console.log(0 in arr1);//true 因为有值 虽然是undefined
console.log(0 in arr2);//false 因为数组中并没有值

arr1.length = 100;
arr1[99] = 123;
console.log(99 in arr1);//true
console.log(98 in arr);//false

var arr = [,,];//也相当于一个稀疏数组
console.log(0 in arr);//false

//数组方法

//1. join (将数组转换为字符串)
var arr = [1,2,3];
console.log(arr.join());//1,2,3
console.log(arr.join("_"));//1_2_3

function repeatString(str,n){
    return new Array(n + 1).join(str);
}
var string = repeatString("a",3);
console.log(string);//aaa

console.log(repeatString("Hi",5));//HiHiHiHiHi

//2. reverse (将数组逆序) (会将原数组修改)
var arr = [1,2,3];
arr.reverse();
console.log(arr);//[ 3, 2, 1 ]

//3. sort (排序) (原数组会被修改)
var arr = ["b","d","a","c"];
console.log(arr.sort());//[ 'a', 'b', 'c', 'd' ]

arr = [13,24,51,3];//会将元素转化为字符串然后再排序 并不会按照数字大小排列
console.log(arr.sort());//[ 13, 24, 3, 51 ]

//按照数字大小排列方法
arr.sort(function(a,b){
    return a - b;
});
console.log(arr);//[ 3, 13, 24, 51 ]

//排列对象元素
arr = [{age:25},{age:39},{age:99}];
arr.sort(function(a,b){
    return a.age - b.age;
});

arr.forEach(function(item){
    console.log('age',item.age);
});
//输出 age 25  age 39  age 99

//4. concat (数组合并)(不会修改原数组)
var arr = [1,2,3];
var newArr = arr.concat(4,5);
console.log(newArr);//[ 1, 2, 3, 4, 5 ]
console.log(arr);//[ 1, 2, 3 ]

newArr = arr.concat([10,11],13);//会将元素都取出后再合并
console.log(newArr);//[ 1, 2, 3, 10, 11, 13 ]

newArr = arr.concat([1,[2,3]]);//只能取出一层 所以参数是数组并且里边的元素还有数组的话 合成的数组会带有数组元素
console.log(newArr); //[ 1, 2, 3, 1, [ 2, 3 ] ]

//5. slice (返回数组的一个片段)(不会修改原数组)
var arr = [1,2,3,4,5];
var newArr = arr.slice(1,3);
console.log(newArr);//[ 2, 3 ]
console.log(arr);//[ 1, 2, 3, 4, 5 ]

newArr = arr.slice(1);//第二个元素省略会从第一个参数的下标取到最后
console.log(newArr);//[ 2, 3, 4, 5 ]

newArr = arr.slice(1,-1);//-1代表取到倒数第二个元素
console.log(newArr);//[ 2, 3, 4 ]

newArr = arr.slice(-4,-3);
console.log(newArr);//[ 2 ]

//6. splice (数组拼接)(会对原数组进行修改)
var arr = [1,2,3,4,5];
var newArr = arr.splice(2);//第一个参数代表从什么地方开始截取
console.log(newArr);//[ 3, 4, 5 ]
console.log(arr);//[ 1, 2 ]

arr = [1,2,3,4,5];
newArr = arr.splice(2,2);//第二个参数代表将要删除的元素的个数
console.log(newArr);//[ 3, 4 ]
console.log(arr);//[ 1, 2, 5 ]

arr = [1,2,3,4,5];
newArr = arr.splice(1,1,'a','b');//可以追加参数 从删除的位置开始添加进去
console.log(newArr);//[ 2 ]
console.log(arr);//[ 1, 'a', 'b', 3, 4, 5 ]

//7. forEach
var arr = [1,2,3,4,5];
arr.forEach(function(x,index,a){
    console.log(x+"|"+index+"|",+(a===arr)+"\n");
});

//打印结果
// 1|0| 1
// 2|1| 1
// 3|2| 1
// 4|3| 1
// 5|4| 1

//8. map (数组映射) (不会修改原数组数据)
var arr = [1,2,3];
var newArr = arr.map(function(x){
    return x + 10;
});
console.log(newArr);//[ 11, 12, 13 ]
console.log(arr);//[ 1, 2, 3 ]

//9. filter (数组过滤) (不会修改原数组数据)
var arr = [1,2,3,4,5,6,7,8,9,10];
var newArr = arr.filter(function(x,index){
    return index%3===0 || x>=8;

});
console.log(newArr);//[ 1, 4, 7, 8, 9, 10 ]
console.log(arr);//[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

//10. every&some (数组判断) every表示每一个元素都要符合指定的条件 some表示只需要有一个元素符合就可以
var arr = [1,2,3,4,5];
var b = arr.every(function(x){
    return x < 10;
});
console.log(b);//true

var b1 = arr.every(function(x){
    return x < 3;
});
console.log(b1);//false

var arr = [1,2,3,4,5];
var b2 = arr.some(function(x){
    return x === 3;
});
console.log(b2);//true

var b3 = arr.some(function(x){
    return x === 100;
});
console.log(b3);//false

//11. reduce & reduceRight reduce是将数组中的元素两两之间执行特定的操作
var arr = [1,2,3];
var sum = arr.reduce(function(x,y){
    return x + y;
},0);
console.log(sum);//6
console.log(arr);//[ 1, 2, 3 ]

arr = [3,9,6];
var max = arr.reduce(function(x,y){
    console.log(x + "|" + y);
    return x > y ? x : y;
});
//3|9
//9|6
console.log(max);//9

//reduce 是从左往右 reduceRight是从右往左
max = arr.reduceRight(function(x,y){
    console.log(x+"|"+y);
    return x > y ? x : y;
});
//6|9
//9|3
console.log(max);//9

//12. indexOf & lastIndexOf (数组检索,检索元素在数组中的位置) 
//indexOf是从左往右查 lastIndexOf是从右往左查
var arr = [1,2,3,2,1];
console.log(arr.indexOf(2));//1
console.log(arr.indexOf(99));//-1 没有回返回-1
console.log(arr.indexOf(1,1));//4 从第二个元素开始查找
console.log(arr.indexOf(1,-3));//4 
console.log(arr.indexOf(2,-1));//-1
console.log(arr.lastIndexOf(2));//3 从右往左查找
console.log(arr.lastIndexOf(2,-2));//3 
console.log(arr.lastIndexOf(2,-3));//1

//11. Array.isArray(Object) 判断是否为数组
var arr = [1,2,3];
console.log(Array.isArray(arr));//true
//还可以用以下方法判断对象是否为数组

console.log(arr instanceof Array);//true
console.log(({}).toString.apply(arr));//[object Array]
console.log(arr.constructor === Array);//true

//字符串和数组  字符串是一种类似数组但不是数组的对象
var str = "hello world";
console.log(str.charAt(0));//h
console.log(str[1]);//e

var a = Array.prototype.join.call(str,"_");
console.log(a);//h_e_l_l_o_ _w_o_r_l_d
上一篇下一篇

猜你喜欢

热点阅读