您的位置:首页 > Web前端 > JavaScript

Js深入浅出(数据、表达式运算符、语句、对象篇)

2018-03-31 14:10 429 查看

数据类型

2.js隐式转换

关于+-

例如:

var x = 10 + 5 ; //15
var x = "10" + 5; //105
var x = "10" - 5 //5


加号可以是加法运算 也可以是字符串拼接,

减号则直接是减法运算

变量num转换为数字:num - 0

变量num转换为字符串:num + “”

== 等于

===严格等于(类型必须相同)

null === null
undefined === undefined
NaN  ≠≠≠ NaN
object ≠≠≠ object  //对象比较的是对象的引用  不是具体的对象


3.js包装对象

包装对象:就是将基本类型(number、string、boolean)包装成对象类型。

举个栗子~~~

假如str是一个字符串类型,不是对象类型。它的属性赋值并不会被保存。所以str.t 值为undefined。只有对象类型的属性赋值会被保存。

var str = 'string'
alert(str.length) // 6
str.t = 10
alert(str.t)// undefined


当把一个基础数据类型尝试用对象的方法, 添加属性的时候, js会尝试先把基础类型转化成对应的基础类型包装对象, 但是当完成这个访问以后 , 这个临时的包装对象就会立即被销毁, 所以str.t的值是undefined

4.js类型检测

typeof 适合基础类型和函数类型的检测 , 不适合其他对象类型的检测

例如:

alert(typeof 123)     //输出数字类型  number
alert(typeof "str")   //输出字符串类型 string
alert(typeof true)    //输出布尔类型  boolean
alert(typeof undefined)  //输出undefined类型  undefined
alert(typeof new Object())  //输出对象类型  object
alert(typeof [1,2])      //数组 输出对象类型  object
alert(typeof function(){})   //函数对象 输出function类型
alert(typeof NaN)     //输出number
alert(typeof null)   //由于历史原因,输出对象类型  object,而不是 null类型


instanceof用来区分引用类型和基本数据型,适用于检测原生对象

obj instanceof Object: 左边的操作对象obj的原型链上是否有右边的构造函数的prototype属性

例如:

function Student(){}
function People(){}
Student.prototype=Person() //Student的原型指向person()对象的原型
var one=Student();
one instanceof Student//one的原型指向Student返回true
one instanceof Person//one的原型先指向Student的原型,发现不对,原型链上移,指向Person的原型,返回true


Object.prototype.toString 判断对象数组、函数

例如:

alert(Object.prototype.toString.apply([]))  //输出[object Array]
alert(Object.prototype.toString.apply(function(){}))  //输出[object Function]


constructor

duck type

表达式和运算符

1.js表达式

1.初始化表达式

1)原始表达式

常量,直接量 eg:3.14 “test”

2.关键字 eg: null this true

3.变量 i,j k

2)复合表达式 eg: 21*3

[1,2] -> new Array[1,2]

[1,,4] -> [1,undefined,undefined,4]

{x:1,y:2} -> var o = new Object();

o.x=1;o.y=2

2.函数表达式

var fe =function(){};

(function(){ console.log(‘hello world’);})();

3.属性访问表达式

var o ={x:1};

o.x o[‘x’]

4.调用表达式

func()

5.对象创建表达式

new Func(1,2)

new Obiect()

语句

1.函数

函数声明:function foo(*){+}

函数表达式:var foo = function(*){+}

构造函数:var foo = new Function(‘’*,’’);

注:函数申明可以预先处理。而函数表达式不能

2.语句

for…in语句

for-in是为普通对象设计的,你可以遍历得到字符串类型的键,因此不适用于数组遍历。

for-in遍历方式的循环计数器是字符串类型,遍历对象时为对象属性/方法名,遍历数组时为数组元素下标索引,与普通的for循环不同,for-in会将继承的属性/方法列出。

注意:

1顺序不确定(依赖于引擎的实现)

2.enumerable标签为false时不会出现

3.for in对象属性时受原型链影响

switch语句

var val = 2
switch(val){
case 1:
console.log(1);
break;
case 2:
console.log(2);
break;
default:
console.log(0);
break;
}
//输出2


循环语句

while(isTrue){
//do sth
}

4000
----------

do{
//do sth
}while(isTrue)

----------

for(var i = 0; i < len; i++){
}


3.JS的严格模式

定义和优点:严格模式是一种特殊的执行模式,它修复了部分语言上的不足(禁用with),提供了更强的错误检查(重复属性,删除delete不可配置的属性等),并增强了安全性(在eval中使用独立作用域等);

模式的使用:

(1)function func(){‘use strict’;}好处:向上兼容

(2)’use strict’; function func(){}指定整个js内的代码都是在严格模式下

与普通模式的区别:

在严格模式下,

①不允许使用with;

②不允许未声明的变量被赋值

③arguments变为参数的静态副本,不管参数传与不传,对arguments无影响,但是对象的属性除外;

④delete参数,函数名报错

⑤delete不可配置的属性报错

⑥对象字面量重复属性名报错

⑦禁止八进制字面量

⑧eval,arguments变为关键字,不能作为变量、函数名

⑨eval变为独立作用域,其它地方不可以拿到eval的值;

对象

1.对象概括

对象中包含一系列属性,这些属性是无序的,每个属性都是一个字符串key和对应的value。

var obj = {x:1,y:2};
obj.x;//1
obj.y//2
//或
var obj = {}
obj[1] = 1;
obj['1'] = 2;
obj//Object{1,2}


2.对象结构



3.对象属性

读取对象属性:

属性异常

删除属性

检测属性

枚举属性

属性异常



*删除属性

var定义的全局变量和局部变量,不可以delete掉,reutrn false。

不使用var 则可以删除掉;

eval(“var ss = ‘aaa’;”);

eval出来的变量是可以delete掉的。(直接或者在函数作用域里面都可以!)



检测属性



cat.hasOwnProperty(“lets”); //true, hasOwnProperty()表示在对象上查找

cat.hasOwnProperty(“toString”) ; //false, 对象上没有toString,原型上才有

cat.propertyIsEnumerable(“lets”); //true,可枚举的属性

cat.propertyIsEnumerable(“toString”); //false,不可枚举的属性

对象是否拥有某个属性,判断的方法有很多,常用的方法就是object.hasOwnProperty(‘×××’),这个方法是不包括对象原型链上的方法的。

举个例子:

var obj = {
name:'fei'
}
console.log(obj.hasOwnProperty('name'))//true
console.log(obj.hasOwnProperty('toString'))//false


在这个例子中,obj对象存在的name属性的时候,调用这个方法才是返回true,我们知道其实每个对象实例的原型链上存在toString方法,在这里打印false,说明这个方法只是表明实例对象的属性,不包括原型链上的属性。

下面我们再来看看in的使用,例子如下:

var obj = {
name:'fei'
}
console.log('toString' in obj)//true


我们可以看到,其实在这个例子中,我只是给了对象一个属性name,并没有其他的属性,然后我执行’tiString’ in obj,可以看出控制动态打印出来的是true,原因就是对象的原型链上存在toString方法,所以in操作不管是不是原型链上,只要存在这个属性,返回的就是true。

接着我们再看for in。在使用for in 循环的时候,其实返回的是能通过对象访问的,可枚举的,包括实例中的,也包括原型中的,例子如下

var obj = {
name:'fei',
age:20,
friend:["fei","jun","zhu"]
}
for( var i in obj){
console.log(i)//会打印三次,name,age,friend


为什么上面没有打印原型中的属性呢,因为原型中的属性都默认设置了不可枚举(enumerated);我们将例子改成下面这样:

var obj = {
name:'fei',
age:20,
friend:["fei","jun","zhu"]
}
Object.defineProperty(obj, 'like', {//使用Object.defineProperty()方法可以设置你设置属性的特性
enumerable:false,//设置不可枚举
value:'basketball'//值为basketball
})
console.log(obj)//Object {name: "fei", age: 20, friend: Array[3], like: "basketball"}

for(var i in obj){
console.log(i)//依旧打印三个name,age,friend


从这个例子中可以看出,在给属性设置为不可枚举的时候,是不会出现在for in循环中的,这也造成IE低版本出现bug,就是不可枚举的属性不会出现在for in中,如果你从新定义了一个属性和原型的属性相同,那么这个属性也不会出现在for in中,现在的浏览器不会出现,

例子如下:

var obj = {
toString:function(){
return "666"
}
}
for(var i in obj){
if(i=="toString"){
console.log('我出现了') //在低版本的IE中不显示
}
}


4.要取得所有可枚举的对象,可以使用ECMAscript5的方法Object.keys(),接受一个对象为参数,返回所有可枚举的属性的字符串数组:

function People(){

}
People.prototype.say = function(){
console.log('say')
}
People.prototype.name = "feifei";

var people = new People()
people.age = 12;

console.log(Object.keys(people))//['age'] Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组


这个方法并不会包含原型链中的属性,只是实例中的可枚举的属性。

获取实例中所有属性,无论是否可枚举,利用Object.getOwnPropertyNames(),以对象为参数,返回熟悉的数组。例子:

function People(){

}
People.prototype.say = function(){
console.log('say')
}
People.prototype.name = "feifei";

var people = new People()
people.age = 12;
Object.defineProperty(people, 'like', {//使用Object.defineProperty()方法可以设置你设置属性的特性
enumerable:false,//设置不可枚举
value:'basketball'//值为basketball
})
console.log(people)//People {age: 12, like: "basketball"}
console.log(Object.getOwnPropertyNames(people))//["age", "like"]


这个方法仅仅是返回实例中所有的属性,无论是不是可枚举的,不包括原型里面的属性。

判断属性是否存在的方法



最后:

比如:

var obj={x:function(){alert(“happy”);}}

obj.x //输出function(){alert(“happy”);}

obj.x() //弹出alert警告框:happy

属性带上括号,就是调用了它的函数,直接输出函数的结果值。

而属性不带括号,输出的就是完整的函数代码,不执行函数。

4.属性读写

get和set方法,能够直接操作对象属性实现读写

直接在对象内设置

var obj1 = {
name: 'shaanxi',
get nameGet() {
return this.name + 'a';
},
set nameSet(name) {
this.name = name;
}
};

console.info(obj1.nameGet);  //shaanxia
obj1.nameSet = 'set by set keywords';
console.info(obj1.nameGet);  //set by set keywordsa


使用原型方法进行设置

var obj3 = {
name: "shaanxi"
};
Object.defineProperties(obj3, {
nameGet: {
value: function() {
return this.name;
}
},
nameSet: {
value: function(name) {
this.name = name;
}
}
});

console.info(obj3.nameGet());  //shaanxi
obj3.nameSet('set by Object.defineProperty');
console.info(obj3.nameGet());  //set by Object.defineProperty




5.查找属性标签

Object.getOwnPropertyDescriptor(o,name)方法用于查询一个属性的描述符,并以对象的形式返回

例如:

var obj = {a:1};
//Object {value: 1, writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(obj,'a'));
//undefined
console.log(Object.getOwnPropertyDescriptor(obj,'b'));


查询obj.a属性时,可配置性、可枚举性、可写性都是默认的true,而value是a的属性值1

查询obj.b属性时,因为obj.b属性不存在,该方法返回undefined

创建属性标签的方法: defineProperty(参数1-对象,参数2-属性名,参数3-具体每个属性的值)



创建多个属性标签的方法: defineProperties(参数1-对象,参数2-每个属性都是对象)



访问所有属性标签的方法: getOwnPropertyDescriptor(对象,属性名)



属性里可以添加get/set方法



总结



value: 属性值

writable: 该属性是否可写,可改变

enumerable:该属性是否可被枚举,就是可在for in中出现

configurable: 该属性的标签是否可改变,是否可用delete将该属性删除。

用defineProperty定义属性时,默认configurable为true,如果设置为false后,该属性不管是什么方式都无法更改。

6.对象标签

extensible标签

isExtensible(obj)可扩展、

preventExtensions(obj)阻止扩展(没有改变属性标签的值)

seal(obj)方法在preventExtensions基础上阻止扩展,区别在于configurable为false

Object.isSealed(obj); //true 判断对象obj是否被隐藏

freeze()方法,比seal()强度更高,更严格。

Object.isFrozen(obj); //true 判断对象是否被冻结

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: