1-js中的数据类型
js中的原始数据类型有6中,其中基本数据类型有4种(string、number、boolean、undefined),引用数据类型有2种(object、null)。
- 值类型在赋值的时候会将数据复制一份进行赋值,各自的改变不会影响到对方
- 引用类型间相互赋值时赋值的是引用的地址。这个地址指向的是同一个对象,任何一个发生改变, 其他引用同一个地址的对象也发生改变
原始数据类型如下:
1.string
2.number
3.boolean
4.undefined
5.null
6.object
2-js的内置对象
1、Arguments //函数参数集合 //arguments['ɑːgjʊm(ə)nts]参数/
2、Array //数组
3、Boolean //布尔对象
4、Date //日期时间对象
5、Error //异常对象
6、Function //函数构造器
7、Math //数学对象
8、Number //数组对象
9、Object //基础对象
10、RegExp //正则表达式对象
11、String //字符串对象
// 下面这两个不用理会
12、Global // 全局对象 //windou对象已经把global对象的方法实现了
13、ActiveXObject // 微软实现的对象
3-等于和全等于的区别
==会自动进行类型转换
===则不会自动进行类型转换
== 只判断值是否相等。如:console.log(null == undefined); //true
=== 判断值和类型是否相等。如: console.log(null === undefined); //false
'a' === new String('a'); // flase
'a' === new String('a').toString(); // true
'a' == new String('a'); // true 自动类型转换
4-for in 循环
for in 语句用于对数组或者对象的属性进行循环操作
for in 操作对象
- for(var key in obj):遍历对象的键
- obj[key]:取对象的键所对应的值
- 一般使用for in 遍历对象是否包含某个属性,属性就是key对应的字符串
var obj = {
name : "Davy",
age : 22
};
for (var key in obj) {
if(obj.hasOwnProperty(key)){
//是obj自己的属性,可以对属性进行操作
}
};
for in 操作数组(不建议使用for in遍历数组,推荐使用for遍历数组)
- var arr = [4, 6, 3, 4];
- 在数组中key就是索引index,如:for(index in arr):遍历数组的索引。结果:0 1 2 3
- arr[index]:取数组的键所对应的值。结果:4 6 3 4
- 对象名[属性名],注意这里的属性名 是字符串,在遍历index时会将index隐式转换为字符串
- 如果需要判断一个数组中是否包含某个值,有两种方法,最好通过arr.indexOf(3),结果是返回值第一次被找 到时的索引2,如果值不存在就返回-1
5-in
使用 in 关键字判断 对象 中是否包含某个属性,原型上的属性也包括
// 包括原型上的
if (propertyName in obj){ }
// 不包括原型上的
if(obj.hasOwnProperty(propertyName)){ }
6-delete关键字
delete可以删除对象的属性,返回值为true(成功)或false(失败)。如:delete obj.name;
delete可以删除对象中不存在的变量,结果也是返回true
delete不能删除全局变量
delete不能删除原型上的变量,不管这个变量是否存在自定义的对象中。如:delete obj.toString(); 结构也是true
没有使用var 声明的全局变量可以被删除(没设置 DontDelete标志)
// 1.删除对象属性
var obj = new Object();
obj.name = 'zhangsan';
delete obj.name; // true
console.log(obj.name); // undefined
// 2.在全局作用域中写如下代码。结论:delete不能删除全局变量
var test = 5;
console.log(delete test); // false
console.log(test); // 5
// 3.不能删除原型上的变量或方法
function Person(name) {
this.name = name;
this.sayHi = function () {
console.log('你好,我的名字是'+this.name);
}
}
Person.prototype = {
name: '默认',
toString: function () {
console.log('我是原型上的toString方法');
}
}
var obj = new Person('张三');
console.log(obj.name); // 张三
obj.sayHi(); // 你好,我的名字是张三
obj.toString(); // 我是原型上的toString方法
delete obj.name; // true 删除对象属性
console.log(delete Person.name); // true 不能真的删除
console.log(delete Person.toString()); // true 不能真的删除
console.log(obj.name); // 默认
obj.toString(); //我是原型上的toString方法
// 4.没有使用var 声明的全局变量可以被删除
/* 通过变量声明 而创建的全局 property; 拥有 DontDelete 标志*/
var foo = 1;
/* 通过未声明赋值创建的 global property; 没有 DontDelete 标志*/
bar = 2;
delete foo; // false
typeof foo; // "number"
delete bar; // true
typeof bar; // "undefined"
7-return的作用
return有3种使用方式
return false; // 阻止默认事件发生,如a元素被点击时的默认事件是会打开href属性指向的页面
return true; //返回函数处理后的结果
return; //退出语句所在的函数,该函数内后面的代码将不再执行
// 1.阻止默认事件
function test1() {
return false;
}
// 2.
function test2() {
return true;
}
// 3.结束函数并返回运行结果
function test3 () {
var arr = [];
...
...
return arr;
}
8-typeof 类型判断
typeof用于表达变量内容的类型,返回代表变量内容的字符串。
使用typeof来判断数据类型不是最保险的办法,因为当数据是 Object 或 Array 或 null 时都会显示为object。
最好的办法是使用Object.prototype.toString.call(obj);
或 obj.constructor
typeof 是一元运算符
// 1. 使用typeof检测传递到函数里面的参数的数据类型,不严谨
function checkType (data) {
switch(typeof data){
case 'string':
console.log('string');
break;
case 'number':
console.log('number');
break;
case 'undefined':
console.log('undefined');
break;
case 'boolean':
console.log('boolean');
break;
case 'object':
console.log('object');
break;
case 'function':
console.log('function');
break;
}
}
checkType(123); // number
checkType('123'); // string
checkType(false); // boolean
checkType(null); // object
checkType(); // undefined
checkType({}); // object
checkType([]); // object
checkType(function(){}); // function
// 2. 更严谨的判断数据类型的方法(原型)
function checkTypeFromPrototype(data) {
return Object.prototype.toString.call(data);
}
checkTypeFromPrototype(123); // [object Number]
checkTypeFromPrototype('123'); // [object String]
checkTypeFromPrototype(false); // [object Boolean]
checkTypeFromPrototype(null); // [object Null]
checkTypeFromPrototype(); // [object Undefined]
checkTypeFromPrototype({}); // [object Object]
checkTypeFromPrototype([]); // [object Array]
9-constructor判断数据类型
每个具有原型的对象都会自动获得
constructor
属性。除了arguments、Enumerator、Error、Global、Math、RegExp、Regular Expression等一些特殊对象之外,其他所有的JavaScript内置对象都具备
constructor
属性。例如:Array
、Boolean
、Date
、Function
、Number
、Object
、String
等。在每个对象中都有
constructor
属性,并一直指向创建它的函数(构造函数)。
// 字符串:String()
var str = "张三";
document.writeln(str.constructor); // function String() { [native code] }
document.writeln(str.constructor === String); // true
// 数组:Array()
var arr = [1, 2, 3];
document.writeln(arr.constructor); // function Array() { [native code] }
document.writeln(arr.constructor === Array); // true
// 数字:Number()
var num = 5;
document.writeln(num.constructor); // function Number() { [native code] }
document.writeln(num.constructor === Number); // true
// 自定义对象:Person()
function Person(){
this.name = "CodePlayer";
}
var p = new Person();
document.writeln(p.constructor); // function Person(){ this.name = "CodePlayer"; }
document.writeln(p.constructor === Person); // true
// JSON对象:Object()
var o = { "name" : "张三"};
document.writeln(o.constructor); // function Object() { [native code] }
document.writeln(o.constructor === Object); // true
// 自定义函数:Function()
function foo(){
alert("CodePlayer");
}
document.writeln(foo.constructor); // function Function() { [native code] }
document.writeln(foo.constructor === Function); // true
// 函数的原型:bar()
function bar(){
alert("CodePlayer");
}
document.writeln(bar.prototype.constructor); // function bar(){ alert("CodePlayer"); }
document.writeln(bar.prototype.constructor === bar); // true
10-判断对象是否含有某个属性
判断对象是否含有某个属性有两种方法可以实现。
- (propertyName in obj) 使用in会判断原型链上的属性
- obj.hasOwnProperty(propertyName) 只判断自身是否有该属性,不会判断原型链上的属性
var obj = {};
Object.prototype.hasOwnProperty('toString'); //true
Object.hasOwnProperty('toString'); //false
obj.hasOwnProperty('toString'); //false
console.log('toString' in obj); //true
11-instanceof
判断对象是不是某个对象的实例,返回一个布尔值
如:
(strObj instanceof String)
判断strObj是不是 String的实例
var items = [];
var object = {};
// www.w3cschool.cn
function reflect(value) {
return value;
}
console.log(items instanceof Array); // true
console.log(object instanceof Object); // true
console.log(reflect instanceof Function); // true
12-字符串连接操作
在代码中应尽量少的操作字符串连接,因为在执行字符串连接操作时,结果总是产生一个新的字符串,而非原来字符串的修改版,从而导致效率很低,若干出现拼接大量字符串的操作,可以先把字符串添加到一个数组中,再用数组的
join(',')
方法将字符连接,这样可以提高操作的效率。
// 当处理字符串链接操作时,会生成新的字符串,而非修改原来的字符串
var str = "test";
var strRef = str;
console.log(str === strRef); // true
// 生成新的字符串
str += 'ing';
console.log(str === strRef); // false
console.log(str); // testing
console.log(strRef); // test
// 高效处理字符串的方法
var fruits = ["Banana", "Orange", "Apple", "Mango"];
function concatString(arr) { // 连接字符串
var str = arr.join('');
return str;
}
console.log(concatString(fruits)); // BananaOrangeAppleMango
13-作用域scope
在js语言中只有全局作用域和函数作用域,没有块作用域。
在全局作用域中的变量都属于window对象的属性
function test(){
val = 'test'; // 没有显式定义变量,val为隐式全局变量,在window对象中可以访问到
}
test();
window.val; // test
15-context上下文对象
使用call和apply改变函数上下文对象,从而让不具备某个方法的对象拥有该方法
function setCourse(){
// 改变push方法的上下文
Array.prototype.push.call(arguments,'JavaScript');
console.log(arguments);
}
setCourse('java');
16-条件语句
- if/else
- if / else if
- switch
// 1.if / else
if(condition){ // 条件
// statements 声明
// 满足条件时执行
}else{
// 不满足条件时执行
}
// 2.if / else if
if(condition){
// 满足条件时执行
}else if (condition){
// 满足条件时执行
}else{
// 不满足条件时执行
}
// 3.switch
switch(expression){// 表达式
case 1:
break;
case 2:
break;
case 3:
break;
default:
}
17-循环语句
- for
- for in
- while
- do / while
18-break和continue及return的区别
1.continue结束本次循环,继续执行下一次循环
2.break的作用是立即退出最内层循环或switch语句
3.return是跳出或结束当前所在的函数
var arr = [1,2,3,4,5];
// break语句只能跳出最内层循环,如果有多层for循环时,需要通过标识来结束其他的循环
for (var i = 0; i < arr.length; i++) {
if(i == 2){
break;
}else {
console.log(i);
}
}
19-变量和函数提升
变量:
- 提升被var声明的变量
- 只提升变量名不提升值
var a = 2;
// 上面的代码相当于拆分为下面的两行代码
var a; // 变量提升
a = 2; // 变量赋值
函数:
引擎会在解释JavaScript代码之前首先对其进行编译(由编译器编译)。编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。
代码的运行分为两个阶段,第一个阶段为编译阶段,第二个阶段为执行阶段
- 同名函数,后面的函数会替换前面的函数
- 函数和变量同名,只会提升函数,忽略变量(即不会声明变量,无论变量才函数的前面还是后面)
//变量和函数同名
//在提升的时候,如果有变量和函数同名,会忽略掉变量,只提升函数
// 预解析前
console.log(foo);
function foo(){}
var foo = 2; // 在当前作用域中,如果已经存在foo变量,则不会再声明相同的变量
console.log(foo);
//预解析后,提升后的代码
function foo(){};
console.log(foo);
foo=2;
console.log(foo);
21-私有变量
function PrivateTest(){
var privateVal = 0; // 私有变量
this.getPrivateVal = function(){
return privateVal;
}
}
var obj = new PrivateTest();
obj.getPrivateVal(); // 获取私有变量
22-模块
模块可以有效的避免全局变量的污染
// 使用一个变量接收模块的引用
var module = (function () {
var count = 10;
var privateVal = '私有变量的值';
function getCount() {
return count;
}
function getPrivateVal() {
return privateVal;
}
return {
getCount: getCount,
getPrivateVal: getPrivateVal
}
})();
// 使用模块
console.log(module.getCount());
console.log(module.getPrivateVal());
23-逻辑与逻辑或
// 逻辑与&&
// 必须要同时满足所有条件才返回true
// 逻辑或||: 条件1为true就返回条件1,否则就返回条件2
function test(a){
a = a || 5;
return a + 20;
}
test(); // 25
test(10); // 30
24-js中的关键字
控制流:break 、continue 、for 、for...in 、if...else 、return 、while 、do...while 、switch...case
运算符:逻辑与&& 、或|| 、非! 、delete 、typeof 、void
25-计算机内存最小单元
在计算机中每一个内存单元就是一个字节,一个字节由8个二进制位组成,二进制位是计算机里的最小的信息单元。
// Number类的toString()方法可以将数字类型的值转为对应的进制数再输出
// 默认是以十进制的方式输出
var n = 17;
n.toString(); // "17"
n.toString(2); // 10001
26-异常处理语句
// 方式1
try {
// 可能发生错误的语句
}catch(exception) {
// exception为错误对象,里面有记录为什么错误的信息
}
// 方式2
try {
// 可能发生错误的语句
}catch(exception) {
// exception为错误对象,里面有记录为什么错误的信息
}finally {
// 始终会被执行的代码
}
类型转换
类型的转换分为显示转换和隐式转换
除了null和undefined之外,任何值都有toString()方法,这个方法的执行结果通常和toString()方法的返回结果一致,都是字符类型。
如果强制将null或undefined转换为对象,会抛出类型错误(TypeError)
// 1.显式转换
Number('3'); // 将字符3转换为Number类型 => 3
String('false');// => "false" 或 false.toString()
Boolean([]); // true
Object(3); // => new Number(3)
// 2.隐式转换
x + ''; // 等介于String(x) , 最终结果为字符串类型
+x; // 等介于Number(x) , 最终为数组类型
!!x; // 等介于Boolean(x) , 最终为布尔类型
运算符
-
什么叫做一元运算符? 通过一个值就可以得出结果的运算符叫做一元运算符。如:
typeof
typeof 4.5; // number typeof "xx"; // string
- 使用两个值的运算符叫做二元运算符。如: +
循环和闭包
// 延迟函数每次操作的都是全局中的i,这种写法是错误的
for(var i =1; i <= 5; i++){
setTimeout(function(){
console.log(i); // 6
}, i * 1000)
}
// 正确写法1
for(var i =1; i <= 5; i++){
setTimeout(function(a){
console.log(a);
}, i * 1000, i)
}
// 正确写法2
for(var i =1; i <= 5; i++){
(function(j){
setTimeout(function(){
console.log(j);
}, j * 1000)
})(i);
}
网友评论