var a = 2
console.log(a) // 2
delete a
console.log(a) // 2
b = 3
console.log(b) // 3
delete b
console.log(b) // 报错:'b' is not defined
let a = 2
console.log(a) // 2
console.log(window.a) // undefined
// var:后一个会把前一个的覆盖
var a = 2
var a = 3
console.log(a) // 3
// let
let b = 5
let b = 6
console.log(b) // 报错:'b' already been declared
// var:存在变量提升
console.log(a) // undefined
var a = 2
// 相当于 =>
var a
console.log(a) // undefined
a = 2
// let
console.log(b) // 报错:Cannot access 'b' before initialization
let b = 5
// var
if(true) {
a = 3
var a
console.log(a) // 3
}
// let
if(true) {
b = 5
let b
console.log(b) // Cannot access 'a' before initialization
}
// var
for(var i = 0; i < 3; i++) {
console.log("循环内:" + i) // 分别为:0 1 2
}
console.log("循环外:" + i) // 3
// let
for(let i = 0; i < 3; i++) {
console.log("循环内:" + i) // 分别为:0 1 2
}
console.log("循环外:" + i) // 'i' is not defined
// 使用 Object 顶层对象的 defineProperty() 方法
// 第一个参数:表示在哪个属性上定义
// 第二个参数:自定义属性的名称
// 第三个参数:是一个对象,用于对该自定义属性的描述
Object.defineProperty(window, 'PI', {
value: '3.14', // 属性的默认值
writable: false // 表示该属性是否可改变,true 可变,false 不可变
})
// 使用 const 关键字,并且在声明并赋值
const a = 2
// 错误
const b
b = 3 // 报错:Missing initializer in const declaration
const 定义的变量不属于顶层对象 window
const 定义的变量不允许被重复声明
const 定义的变量不存在变量提升
const 定义的变量会形成暂时性死区
const 定义的变量会形成块级作用域
// 未使用 freeze()
const obj = {
name: 'zhangsan',
age: 12
}
obj.phone = '123456'
console.log(obj) // {name: 'zhangsan', age: 12, phone: '123456'}
// 使用 freeze()
const obj = {
name: 'zhangsan',
age: 12
}
Object.freeze(obj)
obj.phone = '123456'
console.log(obj) // {name: 'zhangsan', age: 12}
// 使用 freeze() 也只能冻结当浅层
const obj = {
name: 'zhangsan',
age: 12,
skill: {
name: 'code',
year: 3
}
}
Object.freeze(obj)
// 如果需要冻结其它层,需要手动冻结
// Object.freeze(obj.skill)
obj.hobby.year= 12
console.log(obj) // {name: 'zhangsan', age: 12, skill: {name: 'code', year: 12}}
// 使用 freeze() 也只能冻结当浅层,如果需要冻结其它层,需要手动冻结
const obj = {
name: 'zhangsan',
age: 12,
skill: {
name: 'code',
year: 3
}
}
Object.freeze(obj)
Object.freeze(obj.skill)
obj.hobby.year= 12
console.log(obj) // {name: 'zhangsan', age: 12, skill: {name: 'code', year: 3}}
let [a, b] = [1,2]
console.log(a, b) // 1 2
let [a, b, c] = [1, 2, [3, 4]]
console.log(a, b, c) // 1 2 [3, 4]
let [a, b, [c]] = [1, 2, [3, 4]]
console.log(a, b, c) // 1 2 3
let user = {name: 'lisi', age: 12}
let {name, age} = user
console.log(name, age) // lisi 12
// 交换位置不影响
let {age, name} = user
console.log(name, age) // lisi 12
// 取别名:如果取了别名,就不能使用原来的名称
let {age: a, name: n} = user
console.log(n, a) // lisi 12
console.log(name, age) // 'name' 'age' is not defined
// 字符串的解构和数组的解构类似
let str = 'helloworld'
let [a, b, c, d, e, f, g, h, i, j] = str
console.log(a, b, c, d, e, f, g, h, i, j) // h e l l o w o r l d
let arr = [1, 2, 3]
for(let i = 0; i < arr.length; i++) {
console.log(arr[i]) // 1 2 3
arr[i] += 1
}
console.log(arr) // [2, 3, 4]
let arr = [1, 2, 3]
/**
* item:当前遍历的数组对象
* index:当前遍历对象的索引
* array:当前正在遍历的数组本身
**/
arr.forEach(function(item, index, array) {
console.log(item, index)
arr[i] += 1
})
console.log(arr)
let arr = [1, 2, 3]
/**
* item:当前遍历的数组对象
* index:当前遍历对象的索引
* array:当前正在遍历的数组本身
**/
let result = arr.map(function(item, index, array) {
item += 1
return item
})
console.log(arr, result) // [1, 2, 3] [2, 3, 4]
let arr = [1, 2, 3]
/**
* item:当前遍历的数组对象
* index:当前遍历对象的索引
* array:当前正在遍历的数组本身
**/
let result = arr.filter(function(item, index, array) {
return item == 2
})
console.log(arr, result) // [1, 2, 3] [2]
let arr = [1, 2, 3]
/**
* item:当前遍历的数组对象
* index:当前遍历对象的索引
* array:当前正在遍历的数组本身
**/
let result = arr.some(function(item, index, array) {
return item == 2
})
console.log(arr, result) // [1, 2, 3] true
let arr = [1, 2, 3]
/**
* item:当前遍历的数组对象
* index:当前遍历对象的索引
* array:当前正在遍历的数组本身
**/
let result = arr.every(function(item, index, array) {
return item== 2
})
console.log(arr, result) // [1, 2, 3] false
let arr = [1, 2, 3]
/**
* prev:当前遍历数组上一次的元素
* curr:当前遍历数组的元素
* index:当前遍历对象的索引
* array:当前正在遍历的数组本身
* reduce 的第二个参数:初始值
**/
let sum = arr.reduce(function(prev, curr, index, array) {
return prev + curr
}, 0)
console.log(sum) // 6
// 示例1:找出数组中的最大值
let arr2= [1,3,7,2,4,6]
let max = arr2.reduce(function(prev, curr) {
return Math.max(prev, curr)
})
console.log(max) // 7
// 示例2:数组去重
let arr3= [1,3,7,2,4,2,3]
let res = arr3.reduce(function(prev, curr) {
prev.indexOf(curr) == -1 && prev.push(curr)
return prev
}, [])
console.log(res) // [1, 3, 7, 2, 4]
let arr = [1, 2, 3, 5, 2]
for(let index in arr) {
console.log(index) // 0 1 2 3 4
}
let arr = [1,2,3,5,2]
let result = arr.find(function(item) {
return item == 2
})
console.log(result, arr) // 2 [1, 2, 3, 5, 2]
let arr = [1,2,3,5,2]
let result = arr.findIndex(function(item) {
return item == 2
})
console.log(result, arr) // 1 [1, 2, 3, 5, 2]
let arr = [1,2,3,4,5]
for(let item of arr) {
console.log(item) // 1 2 3 4 5
}
let arr = [1,2,3,4,5]
for(let value of arr.values()) {
console.log(value) // 1 2 3 4 5
}
let arr = [1,2,3,4,5]
for(let key of arr.keys()) {
console.log(key) // 0 1 2 3 4
}
let arr = [1,2,3,4,5]
for(let [key,value] of arr.keys()) {
console.log(key, value) // 0 1 1 2 2 3 3 4 4 5
}
// DOM
let divDomList= document.getElementByTagName('div')
console.log(divDomList) // HTMLCollection
console.log(divDomList instanceof Array) // false
let boxDomList= document.getElementByClassName('.box')
console.log(boxDomList) // HTMLCollection
console.log(boxDomList instanceof Array) // false
let testDomList= document.querySelectorAll('.test')
console.log(testDomList) // NodeList
console.log(testDomList instanceof Array) // false
let testDomList= document.querySelectorAll('.test')
console.log(testDomList) // NodeList
let arr = Array.prototype.slice.call(testDomList)
console.log(arr) // [] __proto__: Array
arr.push(12)
console.log(arr) // [12]
function func() {
console.log(...arguments) // 1 'abc' true
}
func(1, 'abc', true)
// 定义一个类数组
let arrLike = {
0: 'ES5',
1: 'ES6',
2: 'ES7',
length: 3
}
// 将类数组转为真正的数组
let arr = Array.from(arrLike)
console.log(arr) // ['ES5', 'ES6', 'ES7']
console.log(arr instance Array) // true
let arr1 = new Array(1, 2)
console.log(arr1) // [1, 2] 此时的 length 值为 2
let arr2 = new Array(3)
console.log(arr2) // [empty x 3] 此时的 length 值为 3
// 使用 Array.of()
let arr3 = Array.of(1, 2)
console.log(arr3) // [1, 2] length 值为 2
let arr4 = Array.of(5)
console.log(arr4) // [5] length 值为 1
let arr5 = Array.of(1, true, 'abc', [2,3,5], {name: 'zhangsan'})
console.log(arr5) // [1, true, 'abc', Array(3), {name: 'zhangsan'}] length 值为 5
let arr = [1, 2, 3, 4, 5]
/**
* 第一个参数(必需传):表示复制到指定索引位置
* 第二个参数:元素复制的起始位置
* 第三个参数:停止复制的索引位置 (默认为 array.length)。如果为负值,表示倒数
**/
console.log(arr.copyWithin(1, 3)) // [1, 4, 5, 4, 5]
let arr = new Array(3)
console.log(arr) // [empty x 3]
/**
* 第一个参数(必需传):表示填充的值
* 第二个参数:可选。开始填充位置
* 第三个参数:可选。停止填充位置 (默认为 array.length)
**/
arr.fill(5)
console.log(arr) // [5, 5, 5]
let arr2 = [1, 2, 3, 4, 5]
arr2.fill('test', 2, 4)
console.log(arr2) // [1, 2, 'test', 'test', 5]
let arr = [1, 2, 'a', 4, 5, NaN]
/**
* 第一个参数(必须传):查找的内容
* 第二个参数:可选。表示从该索引位置处开始查找。如果为负值,表示从倒数的索引位置开始查找
**/
console.log(arr.includes('a')) // true
console.log(arr.includes(NaN)) // true
let arr = [1, 2, 'a', 4, 5, NaN]
/**
* 第一个参数(必须传):查找的内容
* 第二个参数:可选。表示从该索引位置处开始查找。如果为负值,表示从倒数的索引位置开始查找
**/
console.log(arr.indexOf('a')) // 2
console.log(arr.indexOf(NaN)) // -1
function func(a, b) {
b = b || '默认值'
console.log(a, b)
}
func('hello') // hello 默认值
// 传数字 0
// 预期结果应该是 hello 0
// 然而实际输出的是 hello 默认值
// 原因是 0 在 JS 中表示的是 false
func('hello', 0) // hello 默认值
function func(a, b = '默认值') {
console.log(a, b)
}
func('hello') // hello 默认值
func('hello', 0) // hello 0
function ajax(url, { data = [], method = 'get', headers = {} } = {}) {
console.log(method)
}
ajax('http://www.baidu.com') // get
ajax('http://www.baidu.com', { method: 'POST'}) // POST
// 行参都不赋值
function func(x, y, z) {
console.log(x, y, z)
}
console.log(func.length) // 3
// 赋一个默认值
function func1(x, y, z = 3) {
console.log(x, y, z)
}
console.log(func1.length) // 2
// 全部赋一个默认值
function func1(x = 1, y = 2, z = 3) {
console.log(x, y, z)
}
console.log(func1.length) // 0
console.log((new Function).name) // anonymous 匿名
console.log((function(){}).bind({}).name) // bound
// 改变 this 指向
function func(x, y) {
console.log(this, x, y)
}
func.bind({name: '将函数的 this 指向这个对象'})('传入到函数的参数最好放到这个圆括号,当然也可以放到前面bind中', '传入到函数的参数2')
let x = 1
function func(x, y = x) {
console.log(y)
}
func(2) // 2
let x = 1
function func(y = x) {
console.log(y)
}
func() // 1
let a = 1
function func(b = a) {
let a = 2
console.log(b)
}
func() // 1
function func(n = m) {
let m = 2
console.log(n)
}
func() // m is not defined
// 扩展运算符
function func(a, b, c) {
console.log(a, b, c)
}
let arr = [1, 2, 3]
console.log(...arr) // 1 2 3
func(...arr) // 1 2 3
// 合并数组
let arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
// ES5 之前
Array.prototype.push.apply(arr1, arr2)
console.log(arr1) // [1, 2, 3, 4, 5, 6]
// or
let temp = arr1.concat(arr2)
console.log(temp) // [1, 2, 3, 4, 5, 6]
// ES6 使用扩展运算符
arr1.push(...arr2)
console.log(arr1) // [1, 2, 3, 4, 5, 6]
// 字符串
let str = 'hello'
console.log([...str]) // ['h', 'e', 'l', 'l', 'o']
// 不定项参数求和
// arguments
function func() {
let sum = 0
Array.prototype.forEach.call(arguments, function(item) {
sum += item
})
return sum
}
console.log(func(1, 2)) // 3
console.log(func(1, 2, 3)) // 6
// Array.from()
function func() {
let sum = 0
Array.from(arguments).forEach(function(item) {
sum += item
})
return sum
}
console.log(func(1, 2)) // 3
console.log(func(1, 2, 3)) // 6
// 剩余参数 rest
function func(...args) {
let sum = 0
args.forEach(function(item) {
sum += item
})
return sum
}
console.log(func(1, 2)) // 3
console.log(func(1, 2, 3)) // 6
let [x, ...y] = [1, 2, 3, 4]
console.log(x) // 1
console.log(y) // [2, 3, 4]
// 第一种方式:声明式
function func() {
console.log('hello world')
}
// 第二种方式:函数表达式形式
let func = function() {
console.log('hello world')
}
// 将函数表达式 ==> 箭头函数
let func = () => {
console.log('hello world')
}
const func = x => {}
const func = () => {}
const func = (x, y) => {}
const func = x => {
return x
}
// 简写为
const func = x => x
const func = (a,b)=> {
return {
value:a + b;
};
};
// 简写为
const func = (a,b) => ({
value: a + b
});
const People = function(name, age) {
this.name = name
this.age = age
}
let people = new People('zhangsan', 12)
console.log(people)
const People = (name, age) => {
this.name = name
this.age = age
}
let people = new People('zhangsan', 12)
console.log(people) // People is not a constructor
let func = () => {
console.log(arguments)
}
func(1, 2, 3) // Identifier 'func' has already been declared
let name = 'zhangsan'
let age = 12
let obj = {
name: name,
age: age
}
// 可以简写为
let name = 'zhangsan'
let age = 12
let obj = {
name,
age
}
let name = "zhangsan"
let a = "age"
let obj = {
name,
[a]: 12
}
console.log(obj) // { name: 'zhangsan', age: 12 }
let obj = {
name: 'zhangsan',
age: 12,
study: function() {
console.log(this.name + '正在学习。。。')
}
}
// 简写为
let obj = {
name: 'zhangsan',
age: 12,
study() {
console.log(this.name + '正在学习。。。')
}
}
console.log(Object.is(2, '2')) // false
console.log(NaN == NaN) // false
console.log(Object.is(NaN, NaN)) // true
console.log(+0 === -0) // true
console.log(Object.is(+0, -0)) // false
let obj1 = {
name: 'zhangsan',
age: 12
}
let obj2 = {
name: 'zhangsan',
age: 12
}
console.log(obj1 == obj2) // false
console.log(Object.is(obj1, obj2)) // false
let obj = {
a: 2,
b: 3,
c: {
d: 4,
e: [1,2,3]
}
}
// 扩展运算符
let obj2 = {...obj}
obj2.a = 10
console.log(obj2) // {a: 2, b: 3, c: { d: 4, e: [1,2,3] }}
console.log(obj == obj2) // false
console.log(Object.is(obj, obj2)) // false
// Object.assign()
let obj3 = {}
Object.assign(obj3, obj)
console.log(obj == obj3) // false
console.log(Object.is(obj, obj3)) // false
// Object
let obj = {
a: 2,
b: 3,
c: {
d: 4,
e: [1,2,3]
}
}
console.log('c' in obj) // true
console.log('d' in obj) // false
// Array
let arr = [1, 2, 3, 'a', 'hello']
console.log('a' in arr) // false
console.log(3 in arr) // true
let obj = {
name: 'zhangsan',
age: 12,
addr: '南京'
}
for(let key in obj) {
console.log(key, obj[key]) // name zhangsan age 12 addr 南京
}
Object.keys(obj).forEach(key => {
console.log(key, obj[key]) // name zhangsan age 12 addr 南京
})
Object.getOwnPropertyNames(obj).forEach(key => {
console.log(key, obj[key]) // name zhangsan age 12 addr 南京
})
Reflect.ownKeys(obj).forEach(key => {
console.log(key, obj[key]) // name zhangsan age 12 addr 南京
})
let target = {}
let source = {
a: 2,
b: {
c: 3,
d: 4
}
}
target = source
source.b.c = 13
console.log(source)
console.log(target)
let target = {}
let source = {
a: 2,
b: {
c: 3,
d: 4
}
}
Object.assign(target,source)
source.b.c = 13
console.log(source)
console.log(target)
let source = {
a: 2,
b: {
c: 3,
d: 4
}
}
let target = {...source}
source.b.c = 13
console.log(source)
console.log(target)
let source = {
a: 2,
b: {
c: 3,
d: 4
}
}
let target = JSON.parse(JSON.stringify(source))
source.b.c = 13
console.log(source)
console.log(target)
/**
* 深拷贝
**/
function deepClone(obj) {
let result = null
if (typeof(obj) == 'object' && obj !== null){
result = obj instanceof Array? [] : {}
for(let key in obj){
result [key] = deepClone(obj[key])
}
} else {
result = obj
}
return result
}
let source = {
a: 2,
b: {
c: 3,
d: 4
}
}
let target = $.extend(true,{},source)
target.b.c = 13
console.log(source)
let source = {
a: 2,
b: {
c: 3,
d: 4
}
}
let target = _.deepClone(source)
target.b.c = 13
console.log(source)
类的属性与方法:
function Person(name, age) {
this.name = name
this.age = age
}
let p1 = new Person("zhangsan", 12)
console.log(p1) // Person {name: 'zhangsan', age: 12}
function Person(name, age) {
this.name = name
this.age = age
}
// 实例方法
Person.prototype.showName = function() {
console.log("my name is " + this.name)
}
let p1 = new Person("zhangsan", 12)
console.log(p1) // Person {name: 'zhangsan', age: 12}
p1.showName() // my name is zhangsan
类的静态属性与静态方法:
function Person(name, age) {
// this.name 这种是实例属性
this.name = name
// this.age 这种是实例属性
this.age = age
}
// 这种是静态属性
Person.count = 0
function Person(name, age) {
// this.name 这种是实例属性
this.name = name
// this.age 这种是实例属性
this.age = age
// 每被实例化一次,count 加 1
Person.count++
}
// 这种是静态属性
Person.count = 0
Person.getCount = function() {
console.log("被实例化" + Person.count + "次")
}
let p1 = new Person("zhangsan", 12)
let p2 = new Person("李四", 16)
// 调用静态方法
Person.getCount() // 被实例化2次
类的继承:
// 父类
function Animal(name) {
this.name = name
}
Animal.prototype.run = function() {
console.log("动物可以行走。。。")
}
// 子类
function Dog(name,age) {
// 构造函数继承
Animal.call(this,name) // 继承父类的属性
this.age = age
}
Dog.prototype = new Animal() // 将子类的原型指向父类的实例
Dog.prototype.constructor = Dog // 将子类原型上的构造函数再指回子类
let d1 = new Dog("wangwang", 5)
d1.run()
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
showName() {
console.log("名字是:" + this.name)
}
}
let p1 = new Person("zhangsan", 12)
console.log(p1)
class Coder extends Person {
constructor(name, age, company) {
super(name, age)
this.company = company
}
showCompany() {
console.log("公司是:" + this.company)
}
}
let c1 = new Coder("lisi", 14, "xxx")
console.log(c1)
c1.showName()
c1.showCompany()
class People {
constructor(name, age) {
this.name = name
this.age = age
this._sex = ""
}
get sex() {
return this._sex
}
set sex(val) {
this._sex = val
}
}
class People {
constructor(name, age) {
this.name = name
this.age = age
this._sex = ""
}
get sex() {
return this._sex
}
set sex(val) {
this._sex = val
}
// 静态属性
static count = 12
// 静态方法
static getNum() {
console.log("123456")
}
}
People.getNum()
console.log(People.count)
let s1 = Symbol()
let s2 = Symbol()
console.log(s1) // Symbol()
console.log(s2) // Symbol()
console.log(s1 === s2) // false
let s1 = Symbol('sym')
let s2 = Symbol('sym')
console.log(s1) // Symbol('sym')
console.log(s2) // Symbol('sym')
console.log(s1 === s2) // false
let s1 = Symbol.for('sym')
let s2 = Symbol.for('sym')
console.log(s1 === s2) // true
let s3 = Symbol.for('symbol')
function func() {
return Symbol.for('symbol')
}
console.log(s3 === func()) // true
const stu1 = 'zhangsan'
const stu2 = 'zhangsan'
const grade = {
[stu1]: { address: 'xxx', tel: '111' },
[stu2]: { address: 'yyy', tel: '222' }
}
console.log(grade) // { zhangsan: { address: 'yyy', tel: '222' }}
// 使用 Symbol
const stu1 = Symbol('zhangsan')
const stu2 = Symbol('zhangsan')
const grade = {
[stu1]: { address: 'xxx', tel: '111' },
[stu2]: { address: 'yyy', tel: '222' }
}
console.log(grade) // { Symbol('zhangsan'): { address: 'xxx', tel: '111' }, Symbol('zhangsan'): { address: 'yyy', tel: '222' }}
console.log(greade[stu1]) // {address: 'xxx', tel: '111'}
function getArea(shape) {
let area = 0
switch(shape) {
case 'Triangle':
area = 1
break
case 'Circle':
area = 2
break
}
return area
}
console.log(getArea('Circle')) // 2
// 使用 Symbol
const shapeType = {
triangle: Symbol(),
circle: Symbol()
}
function getArea(shape) {
let area = 0
switch(shape) {
case shapeType.triangle:
area = 1
break
case shapeType.circle:
area = 2
break
}
return area
}
console.log(getArea(shapeType.circle)) // 2
let set = new Set()
set.add('hello')
set.add(1)
set.add(2).add(5).add('world')
set.delete(1)
set.delete('hello')
set.clear()
let len = set.size
set.has('world') // false
set.forEach(item => {
console.log(item)
})
for(let item of set) {
console.log(item)
}
let arr = [1,2,1,3,5,3,6]
// 去重
let s = new Set(arr)
// 将 set 转为 array
let tmpArr = Array.from(s) // [...s]
let arr1 = [1,2,3,4,5]
let arr2 = [2,5,6,7,8]
let s1 = new Set(arr1)
let s2 = new Set(arr2)
let result = new Set(arr1.filter(item => s2.has(item)))
console.log(Array.from(result)) // [2,5]
let s3 = new Set(arr1.filter(item => !s2.has(item)))
let s4 = new Set(arr2.filter(item => !s1.has(item)))
console.log([...s3,...s4])
let ws = new WeakSet()
let obj = {
name: 'zhangsan'
}
ws.add(obj)
ws.add({
age: 12
})
ws.delete({
age:12
}) // 这种方式不能删除,因为这是引用类型
ws.delete(obj) // 这种方式可以删除
WeakSet 只能存放对象,Set不仅可以存放基础类型,也可以存放对象
WeakSet 不能遍历,Set 可以
WeakSet 是一种弱引用,并不会被垃圾回收机制引用,如果里面的对象消失,WeakSet 也会消失
let m = new Map()
m.set('key1','val1')
let obj = {
name: 'zhangsan'
}
m.set('obj', obj)
m.get('key1')
m.get('obj')
m.has('key1') // true
m.delete('key1')
m.clear()
let len = m.size
m.forEach((value,key) => {
console.log(key,value)
})
for(let [key,value] of m) {
console.log(key,value)
}
for(let key of m.keys()) {
console.log(key)
}
for(let value of m.values()) {
console.log(value)
}
for(let [key,value] of m.entries()) {
console.log(key,value)
}
const a = 12 // 十进制数
const radix = 2 // 将要转为的进制
console.log(a.toString(radix)) // 1100
const b = 1010
const currRadix = 2 // 当前数据的进制
console.log(parseInt(b, currRadix)) // 10
console.log(Number.isFinite(5)) // true
console.log(Number.isFinite(0)) // true
console.log(Number.isFinite(Infinity)) // false
console.log(Number.isFinite('str')) // false
console.log(Number.isFinite(true)) // false
console.log(Number.isNaN(NaN)) // true
console.log(Number.isNaN(12)) // false
console.log(Number.isInteger(12)) // true
console.log(Number.isInteger(12.5)) // false
console.log(Math.trunc(5.5)) // 5
console.log(Math.trunc(-5.5)) // -5
console.log(Math.trunc(true)) // 1
console.log(Math.trunc(false)) // 0
console.log(Math.trunc(undefined)) // NaN
console.log(Math.trunc(NaN)) // NaN
console.log(Math.sign(5.5)) // 1
console.log(Math.sign(-5.5)) // -1
console.log(Math.sign(0)) // 0
console.log(Math.sign(NaN)) // NaN
console.log(Math.sign(true)) // 1
console.log(Math.sign(false)) // 0
console.log(Math.cbrt(8)) // 2
console.log(Math.cbrt(-8)) // -2
console.log(Math.cbrt(0)) // 0
console.log(Math.cbrt(NaN)) // NaN
console.log(Math.cbrt(true)) // 1
console.log(Math.cbrt(false)) // 0
console.log(Math.cbrt(undefined)) // NaN
console.log(Math.cbrt('str')) // NaN