cocos creator程序员笔试题
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, NaN -
null和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()接口清空整个对象池,释放所有的内存。