操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    /*
    *原理:當觸發數據讀取操作時,執行副作用函數并存儲到桶中
    *當設置數據操作時,再將副作用函數從桶中取出并執行
    */
    //用一個全局變量activeEffect存儲被注冊過的副作用函數
    let activeEffect
    //const buket=new Set()
    /*
    *weakMap為弱引用,不影響垃圾回收機制工作,當用戶代碼對一個
    *對象沒有引用關系時,垃圾會收器會回收該對象,避免引起棧堆的溢出
    */
    const bucket=new WeakMap()
    const effectStack=[]
    //定義一個宏任務隊列
    const jobQueue=new Set()
    //定義一個Promose,將一個任務添加到微任務隊列
    const p=Promise.resolve()
    //是否正在刷新隊列
    let isFlushing=false
    //Symbol唯一,可以作為對象屬性標識符使用
    const ITERATE_KEY=Symbol()
    //map的鍵使用
    const MAP_ITERATE_KEY=Symbol()
    //定義一個map實例,存儲原始對象到代理對象的映射
    const reactiveMap=new Map()
    //代表是否追蹤
    let shouldTrack=true
    //定義一個對象,將自定義add方法添加到下面
    const mutableInstrumentations={
    	add(key){
    		//this指向代理對象,通過raw獲取原始數據對象
    		const target=this.raw
    		//是否元素已經存在集合中
    		const hadkey=target.has(key)
    		//直接使用原始數據對象的方法
    		const res=target.add(key)
    		if(!hadkey){
    			trigger(target,key,'ADD')
    		}
    		return res
    	},
    	delete(key){
    		//this指向代理對象,通過raw獲取原始數據對象
    		const target=this.raw
    		//是否元素已經存在集合中
    		const hadkey=target.has(key)
    		const res=target.delete(key)
    		if(hadkey){
    			trigger(target,key,'DELETE')
    		}
    		return res
    	},
    	//map數據類型擁有get和set兩個方法,所以需要添加這兩個方法
    	get(key){
    		//this指向代理對象,通過raw獲取原始數據對象
    		const target=this.raw
    		//是否元素已經存在集合中
    		const had=target.has(key)
    		//追蹤依賴建立響應
    		track(target,key)
    		//直接使用原始數據對象的方法
    		const res=target.get(key)
    		//如果存在,返回結果,遞歸使用reactive返回最終的原始數據而非對象
    		if(!had){
    			return typeof res==='object'? reactive(res):res
    		}
    		return res
    	},
    	set(key,value){
    		//this指向代理對象,通過raw獲取原始數據對象
    		const target=this.raw
    		//是否元素已經存在集合中
    		const had=target.has(key)
    		//獲取舊值
    		const oldValue=target.get(key)
    		//此處為避免污染原始數據,value必須是數據,而不能是代理對象
    		const rawValue=value.raw || value
    		//設置新值
    		target.set(key,rawValue)
    		//如果不存在,說明時add
    		//只有舊值與新值不同才會觸發更新
    		//因為NaN===NaN為false,而NaN!==NaN為true
    		if(!had){
    			trigger(target,key,'ADD')
    		}else if(oldValue!==value && (oldValue===oldValue || value===value)){
    			trigger(target,key,'SET')
    		}
    	},
    	forEach(callback,thisArg){
    		const wrap=(val)=>typeof val==='object' ? reactive(val) : val
    		const target=this.raw
    		//建立響應
    		track(target,ITERATE_KEY)
    		//通過原始對象調用傳遞過去的函數
    		target.forEach((v,k)=>{
    			//手動實現深響應
    			callback.call(thisArg,wrap(v),wrap(k),this)
    		})
    	},
    	[Symbol.iterator]:iterationMethod,
    	entries:iterationMethod,
    	values:valuesIterationMethod,
    	keys:keysIterationMethod,
    }
    //抽離獨立函數
    function iterationMethod(){
    	const wrap=(val)=>typeof val==='object' && val!==null ? reactive(val) : val
    	const target=this.raw
    	//獲取原始迭代器方法
    	const itr=target[Symbol.iterator]()
    	//建立響應
    	track(target,ITERATE_KEY)
    	return {
    		//對象的next方法是迭代協議
    		//調用原始迭代器的next方法獲取value和done
    		next(){
    			const {value,done}=itr.next()
    			return {
    				//如果value不是undifined,進行包裹
    				value:value?[wrap(value[0]),wrap(value[1])]:value,
    				done
    			}
    		},
    		//實現可迭代協議
    		[Symbol.iterator](){
    			return this
    		}
    	}
    }
    //抽離獨立函數
    function valuesIterationMethod(){
    	const wrap=(val)=>typeof val==='object' && val!==null ? reactive(val) : val
    	const target=this.raw
    	//獲取原始迭代器方法
    	const itr=target.values()
    	//建立響應
    	track(target,ITERATE_KEY)
    	return {
    		//對象的next方法是迭代協議
    		//調用原始迭代器的next方法獲取value和done
    		next(){
    			const {value,done}=itr.next()
    			return {
    				value:wrap(value),
    				done
    			}
    		},
    		//實現可迭代協議
    		[Symbol.iterator](){
    			return this
    		}
    	}
    }
    function keysIterationMethod(){
    	const wrap=(val)=>typeof val==='object' && val!==null ? reactive(val) : val
    	const target=this.raw
    	//獲取原始迭代器方法
    	const itr=target.keys()
    	//建立響應
    	track(target,MAP_ITERATE_KEY)
    	return {
    		//對象的next方法是迭代協議
    		//調用原始迭代器的next方法獲取value和done
    		next(){
    			const {value,done}=itr.next()
    			return {
    				value:wrap(value),
    				done
    			}
    		},
    		//實現可迭代協議
    		[Symbol.iterator](){
    			return this
    		}
    	}
    }
    //重寫arr.includes,indexOf,lastIndexOf方法
    const arrayInstumentations={}
    ;['includes','indexof','lastIndexof'].forEach(method=>{
    	const originMethod=Array.prototype[method]
    	arrayInstumentations[method]=function(...args){
    		//先在代理對象中查找,this是代理對象,將結果保存到res中
    		let res=originMethod.apply(this,args)
    		//如果res不存在,說明this.raw拿到了原始數組,再去其中查找,并跟新res的值
    		if(res===false){
    			res=originMethod.apply(this.raw,args)
    		}
    		return res
    	}
    })
    
    //重寫push方法
    ;['push','pop','shift','unshift','splice'].forEach(method=>{
    	const originMethod=Array.prototype[method]
    	arrayInstumentations[method]=function(...args){
    		//在調用原始方法之前,禁止追蹤
    		shouldTrack=false
    		//調用原始防范
    		let res=originMethod.apply(this,args)
    		//調用原始方法之后,允許追蹤
    		shouldTrack=true
    		return res
    	}
    })
    
    /*
    const data={
    	foo:1,bar:2,
    	get tep(){
    		return this.foo
    	}
    }
    */
    /*
    const obj={}
    const proto={bar:1}
    const child=reactive(obj)
    const parent=reactive(proto)
    //使用parent作為child的原型
    Object.setPrototypeOf(child,parent)
    
    //此處打印true,因為代理對象可以通過raw屬性讀取原始數據
    console.dir(child.raw===obj)
    console.dir(parent.raw===proto)
    
    effect(()=>{
    	//會執行兩次
    	console.log(child.bar)
    })
    */
    /*
    let arr=[1,2,3]
    //const obj=readonly(arr)
    const obj=reactive(arr)
    
    //重新建立副作用函數
    effect(
    	()=>{
    		for(const key of obj){
    			console.log(key)
    			document.getElementById('test').innerHTML=key
    		}
    	}
    )
    setTimeout(()=>obj[3]=10,1000)
    */
    /*
    //map 測試
    const key={key:1}
    const value=new Set([1,2,3])
    let map=new Map([[key,value]])
    //const obj=readonly(arr)
    const pa=reactive(map)
    
    //重新建立副作用函數
    effect(
    	()=>{
    		pa.forEach(function (value,key){
    			console.log(value)
    			console.log(value.size)
    			document.getElementById('test').innerHTML=value
    		})
    	}
    )
    setTimeout(()=>pa.set({key:1},1),1000)
    */
    
    /*
    //如果使用pa.get(key)獲取的是原始數據,并不能實現響應,所以這里也要用forEach
    setTimeout(()=>pa.forEach((v,k)=>{
    	v.add(4)
    }),1000)
    */
    
    const pa=reactive(new Map([
    	['key1','value1'],
    	['key2','value2'],
    ]))
    effect(()=>{
    	for(const [key,value] of pa.entries()){
    		console.log(key,value)
    	}
    })
    setTimeout(()=>{pa.set('key3','value3')},1000)
    
    //封裝代理對象,
    //isShallow淺響,應,isReadonly,淺只讀
    function createReactive(obj,isShallow=false,isReadonly=false){
    	return new Proxy(obj,{
    		//對原始數據的代理
    		//攔截讀取操作
    		get(target,key,receiver){
    			//代理對象可以通過raw屬性訪問原始數據
    			if(key==='raw'){
    				return target
    			}
    			if(key==='size'){
    				track(target,ITERATE_KEY)
    				return Reflect.get(target,key,target)
    			}
    			//返回定義在對象mutableInstrumentations下的方法
    			return mutableInstrumentations[key]
    			/*
    			//1.為解決set的this指向問題,Set.prototype.size是訪問器屬性
    			//對于代理對象來說,this指向了代理對象,所以當調用代理對象.size的時候,就會出錯
    			//因為代理對象不存在內部槽,而set存在
    			//為解決這個問題,需要將Reflect.get的第三個參數指定為原始對象
    			//2.當執行p.delete時,delete為方法,所以會報錯因為this始終指向p代理對象。
    			//所以需要把delete方法與原始數據對象綁定
    			if(key==='size'){
    				track(target,ITERATE_KEY)
    				return Reflect.get(target,key,target)
    			}
    			if(key==='delete'){
    				return target[key].bind(target)
    			}
    			
    			//重寫arr.includes方法-=//如果定義的目標是數組,并且key存在于arrayInstrumentations上
    			//那么返回定義再arrayInstrumentations上的值
    			//執行函數時,實際執行的是定義再arrayInstrumentations上的includes方法
    			//bind函數將this指向原始數據對象
    			
    			if(Array.isArray(target) && arrayInstumentations.hasOwnProperty(key)){
    				return Reflect.get(arrayInstumentations,key,receiver)
    			}
    			
    			//因為數組的for of會讀取symbol.iterator屬性
    			//為避免錯誤和性能開銷,要避免副作用函數與之建立響應
    			//如果key的類型是symbol則不進行追蹤
    			
    			if(!isReadonly && typeof key!=='symbol'){
    				track(target,key)
    			}
    			//返回屬性值
    			//如果對象自身不存在該屬性,會從對象原型尋找對應屬性,并調用原型get方法得到最終結果
    			const res=Reflect.get(target,key,receiver)
    			if(isShallow){
    				return res
    			}
    			//深響應
    			
    			//對于obj.foo.bar來說,當修改obj.foo.bar的值時,并不能觸發響應
    			//為了解決這個問題,需要遞歸地調用reactive函數,直到能返回深響應地數據
    			
    			if(typeof res==='object'  && res!==null){
    				
    				//實現深只讀
    				//如果是只讀對象,則調用readyonly對數據,返回只讀對象
    				
    				return isReadonly?readonly(res):reactive(res)
    			}
    			return res
    			*/
    		},
    		//攔擊in操作符讀取屬性值
    		has(target,key){
    			track(target,key)
    			return Reflect.has(target,key)
    		},
    		//攔截for in 循環讀取屬性值
    		ownKeys(target){
    			//將副作用函數和ITERATE_KEY關聯
    			//如果操作的是數組,則用length作為key并建立響應
    			track(target,Array.isArray(target)?'length':ITERATE_KEY)
    			return Reflect.ownKeys(target)
    		},
    		//攔截設置操作
    		set(target,key,newvalue,receiver){
    			//數據是只讀的,則打印錯誤并返回
    			if(isReadonly){
    				console.warn(`屬性${key}是只讀的`)
    				return true
    			}
    			//獲取舊值
    			const oldval=target[key]
    			
    			//如果屬性不存在,說明是添加新屬性,否則是設置已有屬性
    			//Object.prototype.hasOwnProperty檢查當前操作的屬性是否已經存在對象身上
    			
    			//如果代理目標是數組,檢測被設置的索引是否小于數組長度
    			//如果是,為SET操作,否則ADD操作
    			
    			const type=Array.isArray(target)
    				?Number(key)<target.length?'SET':'ADD'
    				:Object.prototype.hasOwnProperty.call(target,key) ? 'SET':'ADD'
    			//設置屬性值
    			target[key]=newvalue
    			//設置屬性值
    			const res=Reflect.set(target,key,newvalue,receiver)
    			//只有舊值與新值不同才會觸發更新
    			//因為NaN===NaN為false,而NaN!==NaN為true
    			//判斷target是否是recever的代理對象
    			if(target===receiver.raw){
    				if(oldval!==newvalue && (oldval===oldval || newvalue===newvalue)){
    					trigger(target,key,type,newvalue)
    				}
    			}
    			return res
    		},
    		//使用內部方法攔截刪除對象屬性操作
    		deleteProperty(target,key){
    			//數據是只讀的,則打印錯誤并返回
    			if(isReadonly){
    				console.warn(`屬性${key}是只讀的`)
    				return true
    			}
    			//檢查屬性是否存在對象身上
    			const hadkey=Object.prototype.hasOwnProperty.call(target,key)
    			//使用Reflect.deleteProperty(target,key)完成屬性刪除
    			const res=Reflect.deleteProperty(target,key)
    			if(res && hadkey){
    				//只有熟悉存在并且成功刪除時才出發更新
    				trigger(target,key,'DELETE')
    			}
    			return res
    		}
    	})
    }
    
    function track(target,key){
    	//console.dir(target)
    	//禁止追蹤時直接返回
    	if(!activeEffect || !shouldTrack) return
    	if(!activeEffect) return target[key]
    	let depsMap=bucket.get(target)
    	if(!depsMap){
    		bucket.set(target,(depsMap=new Map()))
    	}
    	let deps=depsMap.get(key)
    	if(!deps){
    		depsMap.set(key,(deps=new Set()))
    	}
    	
    	deps.add(activeEffect)
    	activeEffect.deps.push(deps)
    }
    
    //通過type來區分操作類型,避免性能開銷
    function trigger(target,key,type,newValue){
    	const depsMap=bucket.get(target)
    	if(!depsMap) return
    	const effects=depsMap.get(key)
    	const effectsToRun=new Set(effects)
    	/*
    	*當操作為ADD并且是數組時
    	*取出與length相關聯的副作用函數
    	*將副作用函數添加到待執行集合中
    	*/
    	if(type==='ADD' && Array.isArray(target)){
    		const lengthEffects=depsMap.get('length')
    		lengthEffects && lengthEffects.forEach(fn=>{
    			if(fn!==activeEffect){
    				effectsToRun.add(fn)
    			}
    		})
    	}
    	/*
    	*當直接設置了數組的length屬性時,只需要對大于新length的元組進行操作即可
    	*如果操作的是數組的length屬性
    	*那么取出大于新length的所有元素對應的副作用函數執行
    	*/
    	if(Array.isArray(target) && key==='length'){
    		depsMap.forEach((effects,key)=>{
    			if(key>=newValue){
    				effects.forEach(fn=>{
    					if(fn!==activeEffect){
    						effectsToRun.add(fn)
    					}
    				})
    			}
    		})
    	}
    	
    	//取得與INTERATE_KEY相關的副作用函數
    	const interateEffects=depsMap.get(ITERATE_KEY)
    	//避免自增導致無限循環
    	//ECMA規范:再調用foreach遍歷set集合時,如果一個值已經被訪問過
    	//但這個值被刪除并重新添加到集合,如果遍歷沒有結束,那么這個值
    	//又會重新被訪問,解決辦法是建立一個新的Set來遍歷
    	effects && effects.forEach(f=>{
    		if(f!=effectsToRun){
    			effectsToRun.add(f)
    		}
    	})
    	//將ITERATE_KEY相關聯的副作用函數6添加到effectsToRun
    	//刪除屬性會導致ITERATE_KEY減少,所以需要重新觸發
    	if(type==='ADD' || type==='DELETE' ||
    		//如果操作的是map,并且是set操作,也應當觸發副作用函數執行
    		//雖然set不改變鍵的數量,但是set需要設置值
    		(type==='SET' &&
    			Object.prototype.toString.call(target)==='[object Map]'
    		)
    	){
    		interateEffects && interateEffects.forEach(effect=>{
    			if(effect!==activeEffect){
    				effectsToRun.add(effect)
    			}
    		})
    	}
    	if((type==='ADD' || type==='DELETE') &&
    		Object.prototype.toString.call(target)==='[object Map]'
    	){
    		const iterateEffects=depsMap.get(MAP_ITERATE_KEY)
    		iterateEffects && iterateEffects.forEach(effect=>{
    			if(effect!==activeEffect){
    				effectsToRun.add(effect)
    			}
    		})
    	}
    	effectsToRun.forEach(fn=>{
    		//如果副作用函數存在調度函數,那么執行調度函數,否則執行原函數
    		if(fn.options.scheduler){
    			fn.options.scheduler(fn)
    		}else{
    			fn()
    		}
    	})
    }
    
    //通過修改第二個參數來實現只讀深淺,此處淺只讀
    function readonly(obj){
    	return createReactive(obj,false,true)
    }
    //此處深只讀
    function shallowReadonly(obg){
    	return createReactive(obj,true,true)
    }
    
    
    
    //當如下代碼運行時,因為reactive是深響應,所以會返回false
    //這是重復創建了代理對象的問題
    //并且使用了map之后,includes(obj)還是false
    //因為includes內部的this指向的是代理對象arr
    
    /*
    //arr測試
    const obj={}
    const arr=reactive([obj])
    console.log(arr.includes(arr[0]))  //false
    console.log(arr.includes(obj))  //false
    */
    /*
    //obj.size測試
    const set=new Set([1,2,3])
    const obj=reactive(set)
    effect(()=>{
    	document.getElementById('test').innerHTML=obj.size
    })
    setTimeout(()=>obj.add(4),1000)
    */
    //深響應
    function reactive(obj){
    	//從map中查找之前創建的代理對象。
    	const existionProxy=reactiveMap.get(obj)
    	if(existionProxy) return existionProxy
    	//創建新的代理對象
    	const proxy=createReactive(obj)
    	//將代理對象存儲到Map中
    	reactiveMap.set(obj,proxy)
    	return proxy
    }
    //實現淺響應
    function shallowReactive(obj){
    	return createReactive(obj,true)
    }
    
    //options對象動態調度副作用函數的執行時機
    function effect(fn,options={}){
    	const effectFn=()=>{
    		//例如effet(function effectFn(){document.body.inntext=obj.ok?obj.text:'not'})
    		//清除工作
    		cleanup(effectFn)
    		//存儲被注冊過的副作用函數
    		activeEffect=effectFn
    		//嵌套的副作用函數
    		//在調用副作用函數前將其壓入棧中,首先壓入的內層副作用函數
    		effectStack.push(effectFn)
    		let res=fn()
    		//調用完之后,將其彈出棧,彈出內層的副作用函數
    		effectStack.pop()
    		activeEffect=effectStack[effectStack.length-1]
    		//返回fn的結果
    		return res
    	}
    	//存儲與該副作用相關的依賴集合
    	effectFn.deps=[]
    	//將options掛在到副作用函數
    	effectFn.options=options
    	if(!options.lazy) effectFn()
    	return effectFn
    }
    
    function cleanup(effectFn){
    	//遍歷副作用函數的deps數組
    	for(let i=0;i<effectFn.length;++i){
    		const deps=effectFn.deps[i]
    		//從依賴集合刪除
    		deps.delete(effectFn)
    	}
    	effectFn.deps.length=0
    }
    
    //微任務隊列
    //何時執行?在options的調度函數中執行,例如
    /*
    effect(()=>{console.log(obj.foo)},
    	scheduler(fn){
    		//執行調度時,將其添加到微任務隊列
    		jobQueue.add(fn)
    		//刷新隊列
    		flushJob()
    	}
    )
    obj.foo++
    obj.foo++
    *最終輸出
    1
    3
    *微任務隊列最終執行的只有一次,而此時obj.foo的值已經是3.
    */
    function flushJob(){
    	//如果正在刷新任務隊列,什么都不做,否則isFlushing=true
    	if(isFlushing) return
    	isFlushing=true
    	//將任務添加到微任務隊列
    	p.then(()=>{
    		jobQueue.forEach(job=>job())
    	}).finally(()=>{isFlushing=false})
    }
    
    /*
    *計算屬性與懶執行
    */
    
    function computed(getter){
    	let value
    	//是否需要重新計算值,true代表需要計算
    	let dirty=true
    	//只有調用value的時候才會執行
    	const effectFn=effect(getter,{
    		//不執行
    		lazy:true,
    		//當值發生變化時,在跳讀器中重新設置diarty。
    		scheduler(){
    			if(!dirty){
    				dirty=true
    				//當計算屬性依賴的響應數據發生變化時,手動調用函數觸發響應
    				trigger(obj, 'value')
    			}
    		}
    	})
    	const obj={
    		get value(){
    			if(dirty){
    				//執行副作用函數
    				value=effectFn()
    				//設置為false,下次訪問時,直接使用原來的值
    				dirty=false
    			}
    			//當讀取value時,手動調用track函數進行追蹤
    			track(obj, 'value')
    			//返回值為fn的值
    			return value
    		}
    	}
    	return obj
    }
    
    /*
    *wach的實現原理
    *當數據發生變化時,執行回調
    */
    function watch(source,cb,options={}){
    	let getter
    	//如果source是函數,則執行函數,否則調用traverse函數遞歸地讀取屬性
    	if(typeof source==='function'){
    		getter=source
    	}else{
    		getter=()=>traverse(source)
    	}
    	//舊值與新值
    	let oldValue,newValue
     	let cleanup
    	function onInvalidate(fn){
    		cleanup=fn
    	} 
    	//對scheduler函數的封裝
    	const job=()=>{
    		newValue=effectFn()
     		if(cleanup){
    			cleanup()
    		}
    		//返回舊值,新值,已經回調給用戶使用
    		cb(newValue,oldValue,onInvalidate)
    		//已經觸發了回調函數,所以這里重新賦值
    		oldValue=newValue
    	}
    	
    	//出發操作,建立回調
    	const effectFn=effect(
    		//調用函數遞歸地讀取數據
    		()=>getter()
    	,{
    		lazy:true,
    		//調度函數
    		scheduler:()=>{
    			//創建微任務隊列,再DOM加載完成后再執行
    			if(options.flush==='post'){
    				const p=Promise.resolve()
    				p.then(job)
    			}else{
    				job()
    			}
    		}
    	})
    	if(options.immediate){
    		job()
    	}else{
    		//調用副作用函數,拿到舊值
    		oldValue=effectFn()
    	}
    }
    
    function traverse(value,seen=new Set()){
    	//如果數據是原始值或者已經被讀取過了,則什么都不做
    	if(typeof value!=='object' || value===null || seen.has(value)) return
    	seen.add(value)
    	//堆對象內部地屬性,遞歸地讀取數據
    	for(const k in value){
    		traverse(value[k],seen)
    	}
    	return value
    }
    
    /*
    watch(()=>obj.foo,(newValue,oldValue)=>alert(oldValue+':'+newValue))
    setTimeout(()=>obj.foo++,1000)
    
    const sum=computed(()=>{
    	document.getElementById('test').innerHTML=obj.tep
    })
    
    //重新建立副作用函數
    effect(function effectFn(){
    	sum.value
    })
    */

    第四季度了,你年初立下的那些Flag已經完成了幾分之幾?是為那長長的清單又添加了新的項目,還是把那些想來簡單卻實施艱難的條款干脆利落地做了減法呢?

    此時的出行領域,也充滿了各種各樣的計算:

    X

    戴森

    身為小家電領域佼佼者的戴森進入我們關注的列表,是從2017年的9月開始:James Dyson爵士宣布斥資20億英磅挺進電動汽車領域,意圖在出行界復制在小家電界革新的美景。

    隨后,雖然研發成果一直未向外界曝露,但戴森在2018年10月底宣布在新加坡建立電動車工廠并開始吸引全球汽車領域研發人才的頻頻動作,慢慢打消著人們對其跨界的疑惑。尤其在今年,從前寶馬及英菲尼迪CEO Roland Krueger的強勢加盟,到5月我們在《X頭條》曾記錄的那些全新的包括車身材質、外型設計以及內飾布局在內的三項汽車專利的獲取,均使得大家對戴森在2021年帶來一輛炫酷、前衛的電動車輛深信不疑。

    畢竟生產一臺內燃機車輛需要30,000個零件,而生產一臺純電動車輛僅需要11,000個零件。生產復雜程度的降低,以及愈發先進的生產設備與工藝的出現,再加上像特斯拉、豐田這樣的先行者還公布出不少專利共享,使得生產制造電動汽車的準入門檻看起來似乎降低了。再加上戴森以及其創始人的研發傳統與技術底蘊,以及真金白銀的巨額投入,確實比市場上不少新勢力品牌顯得可信度更高。

    然而,前幾周剛剛從威爾特郡哈拉文頓(Hullavington)新測試工廠完成一批原型車輛測試,同時新加坡工廠也已經開始建造及制造設備安裝,就在一切看起來都按部就班、井井有條時。上周四,James Dyson爵士向員工發了一封Emil,令業界大跌眼鏡:

    "The Dyson Automotive team have developed a fantastic car; they have been ingenious in their approach while remaining faithful to our philosophies. However, though we have tried very hard throughout the development process, we simply cannot make it commercially viable. We have been through a serious process to find a buyer for the project which has, unfortunately, been unsuccessful so far. I wanted you to hear directly from me that the Dyson Board has therefore taken the very difficult decision to propose the closure of our automotive project.

    This is not a product failure, or a failure of the team, for whom this news will be hard to hear and digest. Their achievements have been immense – given the enormity and complexity of the project. We are working to quickly find alternative roles within Dyson for as many of the team as possible and we have sufficient vacancies to absorb most of the people into our Home business. For those who cannot, or do not wish to, find alternative roles, we will support them fairly and with the respect deserved. This is a challenging time for our colleagues and I appreciate your understanding and sensitivity as we consult with those who are affected.

    Dyson will continue its £2.5bn investment program into new technology and grow our wonderful new University. We will continue to expand at Malmesbury, Hullavington, Singapore and other global locations. We will also concentrate on the formidable task of manufacturing solid state batteries and other fundamental technologies which we have identified: sensing technologies, vision systems, robotics, machine learning, and AI offer us significant opportunities which we must grab with both hands. Our battery will benefit Dyson in a profound way and take us in exciting new directions. In summary, our investment appetite is undiminished and we will continue to deepen our roots in both the UK and Singapore.

    Since day one we have taken risks and dared to challenge the status quo with new products and technologies. Such an approach drives progress, but has never been an easy journey – the route to success is never linear. This is not the first project which has changed direction and it will not be the last. I remain as excited about the future of Dyson as I have always been; our ambitions have never been higher, our ability to invest has never been greater, and the team has never been stronger.

    I am looking forward to our future adventures together."

    James Dyson

    Engineer

    錢不是問題,團隊不是問題,研發進度也不是問題……那叫停電動汽車項目的原因是什么呢?

    據財經媒體與行業媒體猜測,一方面傳統汽車制造商們占盡天時地利并不遺余力的市場保衛戰硝煙四起,一方面紛至沓來的新入者太過擁擠,使得Dyson先生和董事會們越來越看不清楚方向。畢竟他們更熟悉的模式是:研發制造出一個能讓人日思夜想、神魂顛倒的“神奇”的產品,然后用一個足夠的高價賣給你。畢竟除了他家以外,你還能想出哪個品牌電吹風的新型號誕生能炸翻社交媒體?或者具有能讓女生在情人節時當作禮物收下并且欣喜若狂的能力?

    X

    保時捷vs波音

    要說2019年過得最糟心的公司,波音一定會榜上有名,接連兩場空難讓全球各國都對曾被寄予厚望大賣的737 MAX簽發了禁飛令,時至今日都尚未解禁。

    但畢竟是經歷過大風大浪的老戲骨了,深刻明白要保住品牌聲譽,除了如消防員般到處救火以外還急需新鮮事件轉移視線,上周四波音與保時捷共同官宣:雙方將合作開發一種全電動垂直起降飛機,以打造城市的空中交通市場。

    其實保時捷想要上天也不是臨時起意,畢竟在2018年,保時捷咨詢公司(Porsche Consulting)就對此做出了調查與預測:到2025年之后,城市空中交通市場將加速發展。與當前的傳統陸上交通工具相比,城市空中交通解決方案將以更快的速度和更高的效率運送乘客,并且成本更低,具有更大的靈活性。

    對于此項目的合作,保時捷銷售和市場總監Detlev von Platen表示:“保時捷正尋求通過成為高級出行的領先品牌來擴大其作為跑車制造商的業務范圍。從長遠來看,這可能意味著進入出行市場的第三個維度。”

    X

    本田

    本田這位技術宅,仿佛天生就是技術研發的代名詞。然而,就這樣一位從來都堅持對技術開發親歷親為者,居然在上周破天荒地完成了一次(而且是首次)對初創公司的收購:10月7日,本田研發子公司本田R&D有限公司官宣完成對加利福尼亞州初創企業Drivemode的收購,后者成為本田的全資子公司。

    Drivemode是一家專注于安全駕駛智能手機應用開發的初創公司,于2014年成立,同名App于2015年上線。其主要功能是能夠使得駕駛者直接通過語音和超大按鍵對手機上的導航、通話以及信息處理進行目光不離開路面的盲操作,以便換取行車安全。時至今日,Drivemode除了個人用戶以外還可以為車隊用戶和汽車制造商提供不同的車聯解決方案,現已在150個國家/地區擁有超過250萬次的下載量,并且在不少品牌的手機中成為預裝應用。

    擁有如此龐大用戶基礎的Drivemode自成立以來其實一直順風順水,不僅從Panasonic、NEC Capital Solutions等投資者籌集了超過900萬美元的資金,還陸續與Tesla等巨頭展開合作,其中包括在2015年與本田合作開發應用:Xcelerator。

    談到此次收購,本田總裁兼代表董事三部敏宏(Toshihiro Mibe)表示:“為實現為出行創造價值并改善人們的日常生活,這是本田2030年愿景不可或缺的一部分,我們決定進一步加強與Drivemode的合作關系:將Drivemode杰出的人力資源,創新的軟件技術和作為初創公司的豐富經驗與本田的產品開發技術和能力相結合,創造新的價值。我們將努力提供聯網服務,發揮各自的優勢讓客戶滿意?!?/p>

    就在今年4月,本田在研發部門中成立了全新的數字解決方案中心,致力于通過利用數字技術創造新價值。而這次收購,讓本田改變一貫的自主研發而采用買買買,則是典型的1+1>2的計算:一方面本田為Drivemode提供更好的硬件條件以便其更快更好地開發汽車與摩托車駕駛安全、車載互聯的創新功能;另一方面,作為同類型APP中佼佼者的Drivemode,能夠為本田帶來本品牌以外的巨大用戶群體的各種使用數據,可供其對用戶使用習慣等進行深入的分析與洞察,為本田自身的研發與優化提供更廣泛和全面的數據支撐。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有