重学 JavaScript 笔记(一)—— 变量与数据类型

1.变量

1.1 变量规则

  • 变量只能包含字母、下划线、美元符号或数字;
  • 第一个字符不能是数字。
  • ECMAScript 的变量是松散类型的 —— 可以用来保存任何类型的数据,即每个变量仅仅是一个用于保存值的占位符而已。

1.2 定义变量

1.2.1 var —— ES5及之前使用

var name = "jane";

var 没有块级作用域,只有函数级作用域和全局作用域:

  • 函数级作用域:
    在函数内用 var 定义一个变量,则该变量为定义该变量的作用域中的局部变量,函数退出后则销毁。
  • 全局作用域:
    省略 var ,则为全局变量,在函数外的任何地方都可被访问到(不推荐,难维护,且在严格模式下会抛出错误)。

1.2.2 let & const —— ES6 新增

ES6 中增加了 let 和 const :

let 用来定义变量,定义后可更改;
const 用来定义常量,定义后不可更改。

let 和 var 的区别:

  • let 是块级作用域,var 是函数级作用域,let 的作用域更小;
  • let 无变量提升。
    下面定义的变量,在上面使用会报错;
    var有变量提升,下面定义的变量,在上面值为undefined,不会报错。
  • let 同一个变量只能声明一次,而 var 可声明多次。

2. 数据类型

JavaScript 中有基本类型和引用类型两类共七种数据类型。

undefined 用于未定义的值 —— 只有一个 undefined 值的独立类型。
null 用于未知的值 —— 只有一个 null 值的独立类型。
boolean 用于 true 和 false。
number 数字:整数或浮点数。
string 字符串:一个字符串可以包含一个或多个字符。
symbol 用于唯一的标识符。
object 更复杂的数据结构,用于储存数据集合和更复杂的实体。

2.1 基本类型

2.1.1 Undefined

定义:

let a = undefined;

使用var声明变量但未初始化,或初始化其值为undefined。

var message);alert(message);//undefined 

2.1.2 Null

定义:

let a = null;

空对象指针,用于在将来保存对象。这样只要检查变量是否等于null,就知道这个变量内是否已经保存了一个对象的引用。

注:

alert(null == undefined); //true
alert(null === undefined); //false

2.1.3 Boolean

定义:

let a = true;
let b = false;

ECMAScript 中所有类型的值都有与这两个 Boolean 值等价的值,可使用转型函数 Boolean() 进行转换。

  • 非空字符串、非零数值、任何对象都是 true;
Boolean('111') === true
  • 空字符串、数值零或NaN、null、undefined 都是false。
Boolean('text') === true//true
Boolean(2) === true//true
Boolean({}) === true//true
Boolean({name: 'jane'}) === true//true
  • 流控制语句(如if)会自动执行 Boolean 转换。
var message = 'hello';
if(message){alert('value is true');}  //message被自动转换为对应的 Boolean 值(true)。

2.1.4 Number

2.1.4.1 定义
//整数
let num = 12;
//八进制:第一位为0,后面数值若超出范围,则前导零被忽略,将后面数值按十进制解析
let num1 = 070;//八进制的56
let num2 = 079;//无效的八进制数值,解析为79
//十六进制:前两位为0x,后跟十六进制数字
let num3 = 0xa;  //十六进制的10
let num4 = 0x1f//十六进制的31
2.1.4.2 NaN

NaN(非数值)——特殊的数值,本该返回数值的操作数未返回数值的情况,不抛出错误。

1.任何涉及 NaN 的操作都会返回 NaN ,NaN 与任何值都不相等。

alert(NaN == NaN);   //false

2.isNaN()

isNaN() 函数收到一个值后,会尝试将这个值转换为数值,可以转换则返回 false,否则返回 true。

isNaN(true)//false
isNaN(false)//false
isNaN(1)//false
isNaN('1')//false
isNaN('2')//false
isNaN(null)//false
isNaN(undefined)//true
isNaN({})//true
isNaN(function(){})//true
isNaN('2/0')//true
2.1.4.3 数值转换

**Number():**将任何类型转换为数值;

**parseInt():**将字符串转换为整数;

**parseFloat():**将字符串转换为浮点数;

Number()
var num1 = Number("Hello world!"); //NaN
var num2 = Number(""); //0
var num3 = Number("000011"); //11
var num4 = Number(true); //1
parseInt()
var num1 = parseInt("1234blue"); // 1234
var num2 = parseInt(""); // NaN
var num4 = parseInt(22.5); // 22
var num6 = parseInt("70"); // 70
var num8 = parseInt("s2131"); // NaN
var num = parseInt("0xAF", 16); //175
var num1 = parseInt("AF", 16); //175
var num2 = parseInt("AF"); //NaN
指定基数转换:
var num1 = parseInt("10", 2); //2 (按二进制解析)
var num2 = parseInt("10", 8); //8 (按八进制解析)
var num3 = parseInt("10", 10); //10 (按十进制解析)
var num4 = parseInt("10", 16); //16 (按十六进制解析)
parseFloat()
从第一个字符开始解析,始终忽略前导零
var num1 = parseFloat("1234blue"); //1234 (整数)
var num2 = parseFloat("0xA"); //0
var num3 = parseFloat("22.5"); //22.5
var num4 = parseFloat("22.34.5"); //22.34
var num5 = parseFloat("0908.5"); //908.5
var num6 = parseFloat("3.125e7"); //31250000

2.1.5 String

  • String 类型用于表示由零或多个16 位Unicode 字符组成的字符序列,即字符串。
  • 字符串可以由双引号(")或单引号(’)表示,但前后符号应保持一致。
2.1.5.1 定义
var firstName = "Nicholas";
var lastName = 'Zakas';
2.1.5.2 toString()
  1. 数值、布尔值、对象和字符串都有一个 toString() 方法,返回一个对应字符串。
let num = 2; num.toString();//"2"
let flag = true; flag.toString();//"true"
let text = 'hello'; text.toString();//"hello"

数值的 toString() 方法可以传一个参数:输出数值的基数,如下:

var num = 10;
alert(num.toString()); // "10"  不传,默认为10
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(10)); // "10"
alert(num.toString(16)); // "a"
  1. 对象的 toString() 方法
let obj = {name: 'jane'};
obj.toString() //"[object Object]"`
  1. null 和 undefined 没有 toString() 方法。

  2. String():
    不知道要转换的值是不是 null 或 undefined 时,可以使用转型函数 String(),这个函数可以将任何类型的值转换为字符串。String()遵循下列转换规则:

  • 如果值有toString()方法,则调用该方法(没有参数)并返回相应的结果;
  • 如果值是null,则返回"null";
  • 如果值是undefined,则返回"undefined"。
2.1.5.3 String 的其他常用方法
let testStr = 'testStr';
testStr.substr(1,3) //"est" 截取 testStr 从第1个开始,取3个
testStr.substring(1,4)  //"est" 截取 testStr 从第1个开始,到第4个,不包含第4个
testStr.slice(1,4)  //"est" 截取 testStr 从第1个开始,到第4个,不包含第4个
testStr.substring(2,0)  //"te"
testStr.slice(2,0)  //""

2.2 引用类型 —— 对象

JavaScript 中,对象是及其重要的一点。其他六种是原始类型,他们的值只包含一种东西,而对象是用来存储键值对和更复杂的实体的。

2.2.1 创建对象

//“构造函数”语法创建(后面会详细介绍构造函数)
let info = new Object()
//“字面量”语法创建 —— 常用
let info = {
    name: 'jane',   //键"name",值"jane"
    age: 17 //键"age",值17
}

2.2.2 对象操作

先创建一个对象

let info = {
    name: 'jane',   //键"name",值"jane"
    age: 17 //键"age",值17
}
2.2.2.1 添加属性
//使用 .
info.address = 'beijing'//"beijing",此时的 info:{name: "jane", age: 17, address: "beijing"}

//使用 []
info['friend'] = 'tom'//"tom",此时的 info:{name: "jane", age: 17, address: "beijing", friend: "tom"}
2.2.2.2 计算属性

计算属性 —— 在对象字面量中使用方括号,方括号内可以是任何属性名或变量

let s = 'sch'.concat('ool);
info[s] = 'HIT';//此时的 info:{name: "jane", age: 17, school: "HIT"}
2.2.2.3 删除属性
delete info.age//true,此时的 info:{name: "jane", address: "beijing", friend: "tom"}
2.2.2.4 获取对象属性值
//使用 .
info.address//"beijing"

//使用 []
info['friend']//"tom"
2.2.2.5 对象的可枚举与不可枚举

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性。

Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自有属性对应的属性描述符。

(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

语法:

Object.getOwnPropertyDescriptor(obj, prop)
//obj:需要查找的目标对象, prop:目标对象内属性名称

let info = {
    name: 'jane',   //键"name",值"jane"
    age: 17 //键"age",值17
}
let des = Object.getOwnPropertyDescriptor(info, 'name')
//des
{
    value: "jane", //该属性的值
    writable: true,   //当且仅当属性的值可以被改变时为true
    enumerable: true,   //当且仅当指定对象的属性可以被枚举出时,为 true
    configurable: true  //当且仅当指定对象的属性描述可以被改变或者属性可被删除时,为true
}

不可枚举(enumerable:false): 有以下操作会忽略不可枚举的属性。

  • for…in:不可枚举的属性不会被遍历。
  • Object.keys():不可枚举的属性不会被遍历。
  • JSON.stringify():不可枚举的属性不会被转换为字符串。
  • Object.assign(): 不可枚举的属性不会被复制。

2.2.3 对象常用方法

先创建一个对象

let info = {
    name: 'jane',   //键"name",值"jane"
    age: 17 //键"age",值17
}
2.2.3.1 属性检查

1. hasOwnProperty —— object.hasOwnProperty(propertyName),propertyName 必须为字符串

info.hasOwnProperty('name') //true
info.hasOwnProperty('language') //false

2. “key” in object —— key 为要检测的属性

"name" in info  //true
"language" in info  //false
2.2.3.2 对象遍历

先创建一个对象

let info = {
    name: 'jane',   //键"name",值"jane"
    age: 17 //键"age",值17
}
Object.defineProperty(info, 'name', {
  enumerable: true //可枚举
});
Object.defineProperty(info, 'age', {
  enumerable: false //可枚举
});
//在原型链上添加属性 —— 先了解,原型链部分后再看
Object.defineProperty(info, 'eg1', {
  value: 'view',
  enumerable: true //可枚举
});
Object.defineProperty(info, 'eg2222', {
  value: 'unview',
  enumerable: false //不可枚举
})

1. for … in —— 先遍历对象自身的可枚举属性,再遍历继承的可枚举属性。

for (var index in info) {
  console.log('key:', index, 'value:', info[index])
}
//result 只遍历了自身及原型链上的可枚举属性
key: name value: jane
key: eg1 value: view

2. Object.keys() —— 返回自身及原型链上的可枚举属性组成的数组,可通过遍历数组来遍历对象。

Object.keys(info)
//result 返回自身及原型链上的可枚举属性组成的数组
["name", "eg1"]

Object.keys(info).forEach(item=>{
  console.log(item, info[item])
})
//result
name jane
eg1 view

3. Reflect.ownKeys() —— 返回自身及原型链上所有属性组成的数组,可通过遍历数组来遍历对象。

Reflect.ownKeys(info)
//result 返回自身及原型链上的所有属性组成的数组,包括不可枚举属性
["name", "age", "eg1", "eg2222"]

Reflect.ownKeys(info).forEach(item=>{
  console.log(item, info[item])
})
//result
name jane
age 17
eg1 view
eg2222 unview

4. Object.getOwnPropertyNames() —— 返回自身及原型链上所有属性组成的数组(包括不可枚举属性),可通过遍历数组来遍历对象。

Object.getOwnPropertyNames(info)
//result 返回自身及原型链上的所有属性组成的数组,包括不可枚举属性
["name", "age", "eg1", "eg2222"]

Object.getOwnPropertyNames(info).forEach(item=>{
  console.log(item, info[item])
})
//result
name jane
age 17
eg1 view
eg2222 unview

2.3 变量赋值

基本类型数据赋值:
从一个基本类型变量向另一个变量赋值时,会在内存中新建一个地址,存放新的变量和复制过来的值;

let a = 1;
let b = a;
b = 3;  
console.log(a, b)// =>  a = 1; b = 3; a 和 b 的值存在于内存中的两个地址,互不影响。

引用类型数据赋值:
从一个引用类型变量向另一个变量赋值时,同上,但引用类型的值,实际上是一个指针,与初始变量指向同一个堆内存的对象。因此,这两个变量会互相影响。

let s = {name:"jane"};let y = s; y.name="tom";console.log(s, y)
let a = {name: "jane"};
let b = a;
b.name = "tom"; 
b.city="cc";
console.log(a, b) // =>  {name: "tom", city: "cc"} {name: "tom", city: "cc"} a 和 b 的值存在于内存中的两个地址,但值是同一个指针,指向同一个内存中的对象,属性的改变会相互影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值