数据类型
基本类型
- 有6种:
string、boolean、number、symbol(符号)、null、undefined string、boolean、number、symbol这四种被称为原始类型symbol表示独一无二的值,通过Symbol函数调用生成,由于生成的symbol值为原始类型,而new调用生成的object对象,所以Symbol函数不能使用new调用
const s = Symbol();//不能使用 new 操作符
console.log(typeof s); // "symbol"
//Symbol 方法接收一个参数,表示对生成的 symbol 值的一种描述
const s = Symbol('foo');
//即使是传入相同的参数,生成的 symbol 值也是不相等的,因为 Symbol 本来就是独一无二的意思
const foo = Symbol('foo');
const bar = Symbol('foo');
console.log(foo === bar); // false
null和undefined通常被认为是特殊值,这两种类型的值唯一,就是其本身。boolean:以下五个值为false :undefined、null、0、NaN、''(空字符)undefined: 出现undefined 情况
//1.一个变量声明,但未赋值,输出则是undefined;
let a; // undefined
//2.一个function函数中,没有显式return返回值,就默认的返回值是undefined
function test() {
console.log('dddd');
} // 默认返回值是 undefined
//3.函数实参数小于形参数,那么多余的形参是默认是undefined(其实就是该形参还未被赋值)
function say(name,message){
console.log('Hello' + name + message);
}
say('World!’);
//控制台打印出:HelloWorld!undefined
引用类型
- 只有
object对象类型是引用类型.是无序的集合,存放各种值的容器 array和function是对象的子类型- 包装类型: string是基础类型,但是为什么会有属性和方法呢。其实在引用字符串的属性或方法时,会通过调用
new String()的方式转换成对象,引用结束,又会销毁这个临时对象;
typeof 'tester' // 'string'
typeof new String('tester') // 'object'
不仅仅只是字符串有包装对象的概念,数字和布尔值也有相对应的
new Number()和new Boolean()包装对象。null和undefined没有包装对象,访问它们的属性会报类型错误。
类型判断
- typeof
typeof 'seymoe' // 'string'
typeof true // 'boolean'
typeof 10 // 'number'
typeof Symbol() // 'symbol'
typeof null // 'object' 无法判定是否为 null
typeof undefined // 'undefined'
根据以上可以看出,只有
null的判定会有误差。
typeof {} // 'object'
typeof [] // 'object'
typeof(() => {}) // 'function'
只使用typeof 类型并不能判断具体的子类型,上面的 [] {} 就都是object类型
- instanceof
通过
instanceof操作符也可以对对象类型进行判定,其原理就是测试构造函数的prototype是否出现在被检测对象的原型链上。
[] instanceof Array // true
({}) instanceof Object // true
(()=>{}) instanceof Function // true
- Object.prototype.toString() js中终极判定数据类型, 具体用法如下
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call(() => {}) // '[object Function]'
Object.prototype.toString.call('test') // '[object String]'
Object.prototype.toString.call(1) // '[object Number]'
Object.prototype.toString.call(true) // '[object Boolean]'
Object.prototype.toString.call(Symbol()) // '[object Symbol]'
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call(undefined) // '[object Undefined]'
Object.prototype.toString.call(new Date()) // '[object Date]'
Object.prototype.toString.call(Math) // '[object Math]'
Object.prototype.toString.call(new Set()) // '[object Set]'
Object.prototype.toString.call(new WeakSet()) // '[object WeakSet]'
Object.prototype.toString.call(new Map()) // '[object Map]'
Object.prototype.toString.call(new WeakMap()) // '[object WeakMap]'
该方法本质就是依托
Object.prototype.toString()方法得到对象内部属性[[Class]]; 传入原始类型却能够判定出结果是因为对值进行了包装;null和undefined能够输出结果是内部实现有做处理
NaN
NaN 是一个全局对象的属性,NaN是一种特殊的Number类型。
- 什么时候返回NaN
Infinity / Infinity; // 无穷大除以无穷大
Math.sqrt(-1); // 给任意负数做开方运算
'a' - 1; // 算数运算符与不是数字或无法转换为数字的操作数一起使用
'a' * 1;
'a' / 1;
parseInt('a'); // 字符串解析成数字
parseFloat('a');
Number('a'); //NaN
'abc' - 1 // NaN
undefined + 1 // NaN
//一元运算符(注意点)
+'abc' // NaN
-'abc' // NaN
赋值、深|浅拷贝
- 赋值:赋的其实是该对象的在栈中的地址,而不是堆中的数据,即
指针的引用 - 浅拷贝:重新在堆中创建内存,拷贝前后对象的
基本数据类型互不影响,但拷贝前后对象的引用类型因共享同一块内存,会相互影响 - 深拷贝:内存中开辟一块新的区域,对对象中的子对象进行
递归拷贝,拷贝前后的两个对象互不影响
// 对象赋值
let obj1 = {
name : '浪里行舟',
arr : [1,[2,3],4],
};
let obj2 = obj1;
obj2.name = "阿浪";
obj2.arr[1] =[5,6,7] ;
console.log('obj1',obj1) // obj1 { name: '阿浪', arr: [ 1, [ 5, 6, 7 ], 4 ] }
console.log('obj2',obj2) // obj2 { name: '阿浪', arr: [ 1, [ 5, 6, 7 ], 4 ] }
// 浅拷贝
let obj1 = {
name : '浪里行舟',
arr : [1,[2,3],4],
};
let obj3= Object.assign({}, obj1); //浅拷贝
obj3.name = "阿浪";
obj3.arr[1] = [5,6,7] ; // 新旧对象还是共享同一块内存
console.log('obj1',obj1) // obj1 { name: '浪里行舟', arr: [ 1, [ 5, 6, 7 ], 4 ] }
console.log('obj3',obj3) // obj3 { name: '阿浪', arr: [ 1, [ 5, 6, 7 ], 4 ] }
// 深拷贝
var _ = require('lodash');
let obj1 = {
name : '浪里行舟',
arr : [1,[2,3],4],
};
let obj4= _.cloneDeep(obj1);; //深拷贝 这里使用lodash.cloneDeep
obj4.name = "阿浪";
obj4.arr[1] = [5,6,7] ; // 新对象跟原对象不共享内存
console.log('obj1',obj1) // obj1 { name: '浪里行舟', arr: [ 1, [ 2, 3 ], 4 ] }
console.log('obj4',obj4) // obj4 { name: '阿浪', arr: [ 1, [ 5, 6, 7 ], 4 ] }
浅拷贝实现方式
- Object.assign()
let obj1 = { person: {name: "kobe", age: 41},sports:'basketball' };
let obj2 = Object.assign({}, obj1);
- 函数库lodash的_.clone方法
var _ = require('lodash');
var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] };
var obj2 = _.clone(obj1);
console.log(obj1.b.f === obj2.b.f);// true
- 展开运算符... 与 Object.assign ()的功能相同。
let obj1 = { name: 'Kobe', address:{x:100,y:100}}
let obj2= {... obj1}
- Array.prototype.concat()
用于连接两个或多个数组
arrayObject.concat(arrayX,arrayX,......,arrayX)
let arr = [1, 3, { username: 'kobe' }];
let arr2 = arr.concat();
- Array.prototype.slice()
从已有的数组中返回选定的元素
arrayObject.slice(start,end)
let arr = [1, 3, { username: ' kobe' }];
let arr3 = arr.slice();
深拷贝实现方式
- JSON.parse(JSON.stringify()) 利用JSON.stringify将对象转成JSON字符串,再用JSON.parse把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝
let arr = [1, 3, { username: ' kobe' }];
let arr4 = JSON.parse(JSON.stringify(arr));
这种方法虽然可以实现数组或对象深拷贝,但不能处理函数和正则,因为这两者基于JSON.stringify和JSON.parse处理后,得到的正则就不再是正则(变为空对象),得到的函数就不再是函数(变为null)了。 eg:
let arr = [1, 3, { username: ' kobe' },function(){}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan';
console.log(arr, arr4)
- 函数库lodash的_.cloneDeep
var _ = require('lodash');
var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] };
var obj2 = _.cloneDeep(obj1);
- jQuery.extend()
jquery 有提供一個
$.extend可以用来做 Deep Copy
$.extend(deepCopy, target, object1, [objectN])//第一个参数为true,就是深拷贝
eg:
var $ = require('jquery');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f); // false
Window
window.open()方法会直接打开新的窗口显示跳转网页,是window对象的方法。
window.location.assign() 会在当前网页更改url的地址进行跳转,不会弹出新的页面,是location对象的属性。
<input type="button" value="新窗口打开" onclick="window.open('http://www.baidu.com')">
<input type="button" value="当前页打开" onclick="window.location='http://www.baidu.com/'">
JSX
JSX在编译时会被Babel编译为React.createElement方法
to be continue...
m: Model = {} & m = {} as Model
interface Model {
name: string;
like: string:
}
const m: Model = {
name: '',
like: '',
};
const m1 = {} as Model;
console.log(m); //{name: '', like: ''}
console.log(m1); // {}
console.log(m1.name); // undefined