Handlebars
模板引擎,识别HTML中的 {{}} 等
<div id="app">
<span>余额:{{ balance }}元</span>
</div>
<div id="app1"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script>
const source = document.getElementById("app").innerHTML;
const template = Handlebars.compile(source);
let context = {balance: 100}
document.getElementById('app1').innerHTML = template(context);
</script>
当然它还能实现一些条件判断和循环等,这里就不多讲了
Object.defineProperty
配合模板引擎实现一个操作数据及实时改变html的demo
https://7coder.top/demo1-2.html
在一个对象上定义一个新的属性,或者是修改已存在的属性。最终这个方法会返回该对象
Object.defineProperty(someOne, 'name', {
value: '大石', // 属性值
writable: false, // 该属性是否可写,
configurable: false, // 是否可删除
enumerable: false, //是否可for-in或Object.keys中列举出来
}) // sonmeOne.name = b
Object.defineProperty(someOne, 'name', {
get: function(){ // 获取该属性值的回调
return document.getElementById('introduce').innerHTML;
},
set: function(val){ // 设置该属性值的回调
document.getElementById('introduce').innerHTML = val;
}
})
使用Object.defineProperty创建的属性,writable,configurable,enumerable的默认值为false。
get、set不能与 writable、value 同时使用
flow
静态类型检测工具,将javascript从弱类型语言变成了强类型语言
- 基础数据类型检测
// 在定义变量的同时指定数据类型
let str:string = 'a'
let num:nnumber = 1
// 重新赋值
str = 'b' // error
num = 2 // error
支持的基础数据类型有boolean、number、string、null、void(即undefined)
- 复杂类型检测
// 对象类型
let a:Object = {b: 1}
// 对象类型中的 b 属性
let a1:{b:string} = {b: '1'}
// 数组类型
let numberArr: number[] = [1,2,3]
// 数组类型也可以这样写
let numberArr1: Array<number> = [1,2,3]
let booleanArr: Array<boolean> = [false,true]
// 第四个没声明的也可以这样写
let arr: [number,string,boolean] = [1,'2', false, null]
// 自定义类型
export class Observer {
value: string;
constructor (value: string) {
// 省略
}
}
// 指定传入参数类型和返回值类型
function fn(arg:number,arg2:string):Object{
return {
arg,
arg2
}
}
使用flow.js 需要在babel中安装babel-preset-flow-vue
插件
Object.keys
获取对象中所有的key,返回一个数组。
Object.prototype.c=3
let a = {a: 1,b: 2}
// for...in 会返回原型链上的c属性 但Object.keys不会
Object.keys({a: 1,b: 2}) // [a,b]
for(let i in a){} // a,b,c
Object.create(null)
创建纯净对象,可用作数据字典
Object.create(null) // {} 创建一个纯净的对象
let a = {}
举个🌰
可以发现都是创建的一个对象,但是使用bject.create(null)创建的对象不具有原型链上的属性。
那么它有什么好处呢???
再举个🌰
Object.prototype.name="大石";
let my = {age: 18}
console.log(my.name) // 大石
// 我们在创建my这个对象的时候并没有指定name属性,但是他会继承来自父级object的name属性
// 那么如果想判断my.name是否存在的时候就会出现一些意向不到的情况
let you = Object.create(null)
you.age == "18"
console.log(you.name) // undefined
// 使用Object.create(null)则不会出现这样的情况
另一个使用create(null)的理由是,在我们使用for..in循环的时候会遍历对象原型链上的属性,使用create(null)就不必再对属性进行检查了,当然,我们也可以直接使用Object.keys[]。
Object.assign()
合并两个对象
const a = { a: 1, c: 2 }
const b = Object.assign({c: 4, d: 5}, a)
// b = {a:1, c:2, d:5}
Object.prototype.toString.call()
几乎完美判断每一种数据类型
Object.prototype.toString.call('') ; // [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(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局对象 global 的引用
看起来似乎很强大,但是为什么只能说是几乎完美呢
举个🌰
function Person(name, age) {
this.name = name
this.age = ageonePerson
}
var onePerson = new Person("大石", 18);
// 因为它不能判断是不是某一个类的实例
Object.prototype.toString.call(onePerson); // "[object Object]"
// 还是得用 instanceof
console.log(onePerson instanceof Person); // true
end