Javascript部分
Javascript有哪些數據類型? 舉例兩個最常見的內置對象數據類型。
【答案】Number, String, Boolean, Null, Undefined, Object
常見內置對象類型:數組,函數如下一段代碼:
var a = [];
a[100] = 1;
console.log(a.length);
console.log(a[0]);
a[200] = undefined;
console.log(a.length);
console.lolg(a['100']);
請問四條log語句分別輸出什么?
【答案】分別輸出 101,undefined, 201,1
parseInt('1.9'); parseInt('hello')分別返回什么值?
【答案】分別返回 1, NaNnull和undefined的區別。
【參考答案】null表示一個“空”的值,它和0以及空字符串''不同,0是一個數值,''表示長度為0的字符串,而null表示“空”。在其他語言中,也有類似JavaScript的null的表示,例如Java也用null,Swift用nil,Python用None表示。但是,在JavaScript中,還有一個和null類似的undefined,它表示“未定義”。
JavaScript的設計者希望用null表示一個空的值,而undefined表示值未定義。大多數情況下,我們都應該用null。undefined僅僅在判斷函數參數是否傳遞的情況下有用。==和===的區別
【參考答案】==在比較的時候可以自動轉換數據類型。===嚴格比較,不會進行自動轉換,要求進行比較的操作數必須類型一致,不一致時返回flase。函數中this指向什么? call, apply, bind的用法和區別。
【參考答案】this指代函數的運行環境,執行obj.func()時,this指向obj,直接執行func()時,this指向全局環境。
call, apply, bind都可以改變函數執行時的運行環境,即this的指向。
call和apply都是調用時立刻執行的,而bind調用后返回了綁定this對象的原函數,bind比較適合將this綁定后的函數傳入到其他函數中去執行,特別是作為回掉函數異步執行。
call和bind的參數第一個參數是要綁定的對象,后面是要傳入原函數的多個參數;而apply第二個參數必須是一個數組,數組中是要傳入的參數。說說對 prototype和 __proto __ 的理解
【參考答案】prototype是函數才有的屬性,prototype本身也是個函數對象;__proto __是所有對象都有的屬性,__proto __指向構造它的對象的對象的prototype。例如:
> var o = new Object()
o.__proto__ == Object.prototype
< true
o是Object構造出的對象,o的__proto __指向Object的prototype,這樣o可以使用Object.prototype里面的方法。原型鏈:當js查找對象的屬性時,先查找對象自身是否具有該屬性,如果沒有,就會去__proto __指向的prototype對象上查找,直到找到或者__proto __為null
- 使用構造函數實現一個類Foo,需要有屬性 count, 方法bar(), 并且寫出創建該類對象的方法
【參考答案】
function Foo(){
this.count = 0;
}
Foo.prototype.bar = function(){
}
var foo = new Foo();
foo.bar();
- 以下代碼片段輸出是什么,為什么?如果想輸出0,1,2請問如何修改?
var s = [];
function foo() {
for(var i=0; i<3; i++){
s[i] = function(){
console.log(i);
}
}
}
foo();
s[0]();
s[1]();
s[2]();
【參考答案】輸出3,3,3。因為foo()函數執行時生成了三個閉包,這三個閉包綁定了同一個變量i,第三個閉包生成時,i的值為3。因此執行這三個閉包時都會輸出3。
修改為輸出0,1,2的原則是讓三個閉包綁定不同的變量,所以在生成閉包時就要區分出來,一種修改方法如下:
var s = [];
function foo() {
for(var i=0; i<3; i++){
s[i] = function(index){
return function(){
document.write(index);
}
}(i);
}
}
foo();
s[0]();
s[1]();
s[2]();
- 說說ES6為什么要引入let關鍵字
【參考答案】因為要解決var聲明對象產生的問題。
var是函數級作用域,而let是塊作用域。
var存在變量提升,即變量可以在聲明之前使用,值為undefined,而let聲明的變量如果在聲明之前使用會拋出一個錯誤。
另外let不允許重復聲明變量。
ES6 規定暫時性死區和let、const語句不出現變量提升,主要是為了減少運行時錯誤,防止在變量聲明前就使用這個變量,從而導致意料之外的行為。這樣的錯誤在 ES5 是很常見的,現在有了這種規定,避免此類錯誤就很容易了。
Cocos creator部分
cocos creator和cocos2dx的區別
【參考答案】cocos creator是一套包含編輯器在內的開發框架,其內部引擎使用了cocos2d-x js的精簡修改版本。creator使用js/ts語言開發,以內容創作為核心,腳本作為自定義組件添加到場景的節點上。creator中需要動態載入的資源,放在工程的哪個子目錄中
【參考答案】asserts/resources寫出代碼片段:獲取節點node上Label組件,并設置其內容為'hello'
【參考答案】
let label = node.getComponent(cc.Label);
label.string = 'hello';
- 列舉出組件的生命周期回掉函數,并說明其調用時機
【參考答案】
onLoad 組件首次激活時觸發
start 組件第一次執行update之前觸發
update 每一幀渲染前調用
lateUpdate 所有組件update調用后調用
onDestroy 組件或所在節點調用了destroy()時調用,并在當前幀結束時統一回收組件
onEnable 組件的enabled屬性從false變為true時
onDisable 組件的enabled屬性從true變為false時
creator對齊UI控件使用什么組件?如果想制作一個和屏幕大小一樣的節點如何設置該組件
【參考答案】widget組件。設置top,bottom,left,right為0px,且該節點從直接的父節點到場景根節點都必須有widget組件且設置為同屏幕大小。或者1.10之后可設置target為最上層的節點。寫一小段代碼,使用action將節點node在1秒鐘之內從當前位置移動到(100,100)
【參考答案】
var action = cc.moveTo(1, 100, 100);
node.runAction(action);
游戲開發部分
什么是draw call? 為什么減少draw call可以優化游戲速度。如何減少draw call? 在creator中如何做
【參考答案】cpu向gpu提交一次繪制的圖元(頂點)集合即為draw call。draw call太多就會讓gpu反復切換渲染狀態,cpu需要不斷提交數據到gpu,降低幀數。減少draw call就要對需要繪制的圖元進行合并,這樣就要保證這些圖元的渲染狀態(材質)是一樣的,且這些圖元必須是在一起繪制的(中間不要插入別的材質的圖元)。在creator中可使用圖集合并工具如texture packer將sprite合并成到一張貼圖上,并且安排節點的繪制順序,將使用同一張貼圖的節點放到一起繪制。一張1024x1024,32位的貼圖,在內存里面占多少字節?
【參考答案】 1024102432 /8 = 4M字節cocos中sprite的Blend屬性,Src Blend Factor設置為 SRC_ALPHA, Dst Blend Factor設置為 ONE_MINUS_SRC_ALPHA是什么意思,有什么作用?
【參考答案】這表示繪制這個Sprite時,和Frame buffer上面已經有的像素進行混合的公式參數。以上參數設置的公式為: FinalColor = SpriteColor(RGB) * SpriteAlpha + BufferColor(RGB) * (1-SpriteAlpha)。效果是標準的透明圖元渲染。如果做一個射擊游戲,需要發射大量的子彈,為了避免頻繁的申請內存,一般會采取什么方法?這個機制會提供哪些接口供游戲邏輯使用。
【參考答案】會采用對象池/內存對象緩存的機制。一個對象池一般會提供, preAllocat(count)接口預先分配一定數量的對象, get()接口返回一個池里面的空閑對象,put(obj)接口將對象返回到池里面,freeAll()/Clear()接口清空整個對象池,釋放所有的內存。