本篇绪论
1,Object.prototype.toString.call()方法
2,ES6函数参数解构
3,computed、methods、watch区别
1,Object.prototype.toString.call()方法
JS中使用typeof判断基础数据类型:number、string、undefined、null、boolean,对于数组、函数、对象来说都是统一返回object。这时就应该使用Object.prototype.toString.call()来精准的判断数据类型了
Object.prototype.toString.call(null)
Object.prototype.toString.call(undefined)
Object.prototype.toString.call('abc')
Object.prototype.toString.call(123)
Object.prototype.toString.call(true)
Object.prototype.toString.call(function fn () {})
Object.prototype.toString.call(new Date())
Object.prototype.toString.call([1,2,3])
Object.prototype.toString.call({name: 'xiaowang'})

function Person(name, age) {
this.name = name
this.age = age
}
let p = new Person('Rose', 18)
console.log(Object.prototype.toString.call(p)) // [object Object]
// 很明显,这种方法不能准确判断p1是Person的实例,而只能用instanceof进行判断
p instanceof Person // true
toString是Object的原型方法,而Array、function作为Object的实例,都重写了toString方法。
let arr = [1,2,3]
console.log(Array.prototype.hasOwnProperty('toString'))
console.log(arr.toString())
delete Array.prototype.toString
console.log(Array.prototype.hasOwnProperty('toString'))
console.log(arr.toString())
// hasOwnProperty 判断自身属性是否存在

常见面试题:实现一个函数clone,可以对js中的5种数据类型纪念性值复制
function getDataType(data){
var getType = Object.prototype.toString
var myType = getType.call(data)
var typeName = myType.slice(8,-1)
var copyData=''
switch(typeName){
case 'Number':
copyData = data-0
break
case 'String':
copyData = "'" + data + "'"
break
case 'Function':
copyData=data
break
case 'Null':
copyData=null
break
case 'Undefined':
copyData="Undefined"
break
case 'Array':
copyData=[]
for(var i=0;i<data.length;i++){
copyData[i]=data[i]
}
break
case 'Object':
copyData={}
for(var x in data){
copyData[x]=data[x]
}
break
case 'Boolean':
copyData=data
break
default :
copyData=data
break
}
return copyData
}
console.log(getDataType(123))
console.log(getDataType("123"))
console.log(getDataType(null))
console.log(getDataType(undefined))
console.log(getDataType(false))
console.log(getDataType([1,2,4]))
console.log(getDataType({"name":"wc"}))
console.log(getDataType(function(){alert(23)}))

2,ES6函数参数解构
常规的JS,如果给函数传递的参数是一个对象,写法如下
const firstName = 'huahua'
const lastName = 'xiao'
const person = {
firstName,
lastName
}
console.log(person.firstName + ' ' + person.lastName // huahua xiao
以上代码等同于:
const person = {
firstName: firstName,
lastName: lastName
}
ES6的解构是用来给变量赋值的
const person = {
firstName: 'huahua',
lastName: 'xiao'
}
const {firstName, lastName} = person
// 这里的{firstName, lastName}其实就是{firstName: firstName, lastName: lastName}
console.log(firstName + '-' + lastName) // huahua-xiao
解构赋值可以有默认值
const {firstName = 'huahua', lastName = 'xiao'} = {}
console.log(firstName + lastName) // huahua xiao
解构应用在函数参数传递上
function sayName({firstName, lastName} = {}) {
console.log(firstName + ' ' + lastName) // huahua xiao
}
sayName({firstName: 'huahua', lastName: 'xiao'})
传递的参数person会直接取代右边的{firstName: 'lebron'}, 然后被当作真正的解构赋值对象,从而造成firstName没有默认值:
function sayName({firstName, lastName = 'bar'} = {firstName: 'lebron'}) {
console.log(firstName + ' ' + lastName)
}
let person = {
wrongFirstName: 'yy',
lastName: 'xiao'
}
sayName(person) // undefined xiao
3,computed、methods、watch区别
模版内的表达式设计初衷是用于简单的计算。在模版中放入太多的逻辑会让模版过重且难以维护,对于复杂逻辑,vue提倡使用计算属性。
computed、methods区别
理论上,computed所有实现可以使用methods完全替换
以下示例使用computed和methods实现字符串反转
methods:
<p>reverse message: {{ reverseMessage() }}</p>
data () {
return {
message: 'xiaohuahua'
}
},
methods: {
reverseMessage () {
return this.message.split('').reverse().join('') // auhauhoaix
}
}
// split('') 将字符串转为数组
// join('') 将数组转为字符串
computed:
<p>reverse message: {{ reverseMessage }}</p>
data () {
return {
message: 'xiaohuahua'
}
},
computed: {
reverseMessage () {
return this.message.split('').reverse().join('')
}
}
计算属性是基于响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这意味着只要message还没有发生改变,多次访问reverseMessage计算属性会立即返回之前的计算结果,而不必再次执行函数,而方法却会执行
这也就意味着下面的计算属性将不再更新,因为 Date.now()不是响应式依赖
computed: {
now () {
return Date.now()
}
}
打个比方,我们有一个性能开销比较大的计算属性A,它需要遍历一个巨大的数组并做大量的计算,我们可能有其他的计算属性依赖A,如果没有缓存,我们将不可避免的多次执行A的getter。
computed、watch区别
vue提供了一种更通用的方式来观察和相应Vue实例上的数据变动:侦听属性(watch)
当有一些数据需要随着其他数据变动而变动的时候,很容易滥用watch,而通常更好的做法是使用计算属性,细想一下下面的例子
<div id="demo">{{ fullName }}</div>
data () {
return {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
}
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
以上代码是命令式且重复的,将它与计算属性的版本进行比较
data () {
return {
firstName: 'Foo',
lastName: 'Bar'
}
},
computed: {
fullName () {
return this.firstName + '' + this.lastName
}
}
好得多了,不是吗?
网友评论