讲解javascript,讲解器

关于js原型的面试题讲解

今天遇到关于javascript原型的一道面试题,现分析下:

站在用户的角度思考问题,与客户深入沟通,找到牡丹网站设计与牡丹网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、网站设计、企业官网、英文网站、手机端网站、网站推广、国际域名空间、虚拟主机、企业邮箱。业务覆盖牡丹地区。

原题如下:

function

A(){

}

function

B(a){

this.a

=

a;

}

function

C(a){

if(a){

this.a

=

a;

}

}

A.prototype.a

=

1;

B.prototype.a

=

1;

C.prototype.a

=

1;

console.log(new

A().a);

console.log(new

B().a);

console.log(new

C(2).a);

分析:

console.log(new

A().a);//new

A()为构造函数创建的对象,本身没有a属性,所以向它的原型去找,发现原型的a属性的属性值为1,故该输出值为1;

console.log(new

B().a);//new

B()为构造函数创建的对象,该构造函数有参数a,但该对象没有传参,故该输出值为undefined;

console.log(new

C(2).a);//new

C()为构造函数创建的对象,该构造函数有参数a,且传的实参为2,执行函数内部,发现if为真,执行this.a

=

2,故属性a的值为2;

故这三个的输出值分别为:1、undefined、2.

以上就是小编为大家带来的关于js原型的面试题讲解的全部内容了,希望对大家有所帮助,多多支持脚本之家~

javascript 中的泛型详解

首先我们来定义LockingPtr用到的Mutex类的骨架:

class Mutex

{

public:

void Acquire();

void Release();

...

};

为了能使用LockingPtr,你要用你操作系统用到的数据结构和基本函数来实现Mutex。

LockingPtr用受控的变量的类型来作为模板。举例来说,如果你想管理一个Widget,你使用一个LockingPtrWidget,这样你可以用一个类型为volatile Widget的变量来初始化它。

LockingPtr的定义非常简单。LockingPtr实现一个相对简单的smart pointer。它目的只是把一个const_cast和一个临界区集中在一起。

Template typename T

Class LockingPtr {

Public:

//构造/析构函数

LockingPtr(volatile T obj, Mutex mtx)

: pObj_(const_castT*(obj)),

pMtx_(mtx)

{ mtx.Lock(); }

~LockingPtr()

{ pMtx_-Unlock(); }

//模拟指针行为

T operator*()

{ return *pObj_; }

T* operator-()

{ return pObj_; }

private:

T* pObj_;

Mutex* pMtx_;

LockingPtr(const LockingPtr);

LockingPtr operator=(const LockingPtr);

};

尽管简单,LockingPtr对写出正确的多线程代码非常有帮助。你应该把被几个线程共享的对象定义为volatile而且不能对它们使用const_cast——应该始终使用LockingPtr自动对象。我们通过一个例子来说明:

假设你有两个线程共享一个vectorchar对象

class SyncBuf {

public:

void Thread1();

void Thread2();

private:

typedef vectorchar BufT;

volatile BufT buffer_;

Mutex mtx_; //控制对buffer_的访问

}; 软件开发网

在一个线程函数中,你简单地使用一个LockingPtrBufT来取得对buffer_成员变量的受控访问:

void SyncBuf::Thread1() {

LockingPtrBufT lpBuf(buffer_, mtx_);

BufT::iterator I = lpBuf-begin();

For (; I != lpBuf-end(); I) {

...使用*i...

}

}

这些代码既非常容易写也非常容易懂——任何时候你需要用到buffer_,你必须创建一个LockingPtrBufT指向它。一旦你这样做,你就能够使用vecotr的所有接口。

非常好的事情是,如果你犯了错,编译器会指出来:

void SyncBuf::Thread2() {

//错误,不能对一个volatile对象调用begin()

BufT::iterator I = buffer_.begin();

//错误!不能对一个volatile对象调用end()

for (; I != lpBuf-end(); I) {

...使用*i...

}

}

你不能调用buffer_的任何函数,除非你要么使用一个const_cast要么使用LockingPtr。区别是LockingPtr提供了一个有序的途径来对volatile变量使用const_cast。

LockingPtr非常有表现力。如果你只需要调用一个函数,你能够创建一个无名临时LockingPtr对象并直接使用它:

Unsigned int SyncBuf::Size() {

Return LockingPtrBufT(buffer_, mtx_)-size();

}

回到基本类型

我们已经看到了volatile保护对象不被不受控制地访问时是多么出色,也看到了LockingPtr提供了多么简单和高效的方法来写线程安全的代码。让我们回到基本类型,那些加了volatile后行为与用户自定类型不同的类型

我们来考虑一个例子,多个线程共享一个类型为int的变量。

Class Count

{

public:

...

void Increment() { ctr_; }

void Decrement() { --ctr_; }

private:

int ctr_;

};

如果Increment和Decrement被不同线程调用,上面的代码片段是有问题的。首先,ctr_必须是volatile,其次,即使象 ctr_那样看上去是原子操作的函数实际上是一个三步操作。内存本身没有算术能力,当递增一个变量时,处理器:

* 读取那个变量到寄存器

* 在寄存器中增加值

* 把结果写回内存

这个三步操作叫做RMW(Read-ModifyWrite 读-改-写)。在执行一个RMW操作的“改”

操作时,为了让其他处理器访问内存,大多数处理器会释放内存总线。

如果那时另一个处理器对同一个变量执行一个RMW操作,我们就有了一个竟态条件;第二个写操作覆盖了第一个的结果。

你也能够用LockingPtr避免这种情况:

class Counter

{

public:

...

void Increment() { *LockingPtrint(ctr_, mtx_); }

void Decrement() { --*LockingPtrint(ctr_, mtx_); }

private:

volatile int ctr_;

Mutex mtx_;

};

现在代码正确了,但代码质量比较SyncBuf的代码而言差了很多。为什么?因为在Counter里,如果你错误地直接访问ctr_(没有先对它加锁)编译器不会警告你。如果ctr_是volatile, ctr_也能编译通过,但产生的代码明显是错误的。编译器不再是你的帮手了,只有靠你自己注意才能避免这样的竟态条件。

那你应该怎么做?简单地把你用到的基本数据包装为更高层次的结构,对那些结构用volatile。荒谬的是,尽管本来volatile的用途是用在内建类型上,但实际上直接这样做不是个好主意!

volatile成员函数

到目前为止,我们已经有了包含有volatile数据成员的类,现在我们来考虑设计作为更大对象一部分的类,这些类也被多线程共享。在这里用volatile成员函数有很大帮助。

当设计你的类时,你只对那些线程安全的成员函数加voaltile标识。你必须假定外部代码会用任何代码在任何时刻调用volatile函数。不要忘记:volatile等于可自由用于多线程代码而不用临界区,非volatile等于单线程环境或在一个临界区内。

例如,你定义一个Widget类,实现一个函数的两个变化——一个线程安全的和一个快的,无保护的。

Class Widget

{

public:

void Operation() volatile;

void Operation();

...

private:

Mutex mtx_;

};

注意用了重载。现在Widget的用户可以用同样的语法来调用Operation,无论你为了获得线程安全调用volatile对象的Operation还是为了获得速度调用常规对象的Operation。但用户必须小心地把被多线程共享的Widget对象定义为volatile。

当实现一个volatile成员函数时,第一个操作通常是对this用一个LockingPtr加锁。剩下的工作可以交给非volatile的对应函数:

软件开发网

void Widget::Operation() volatile

{

LockingPtrWidget lpThis(*this, mtx_);

LpThis-Operation(); //调用非volatile函数

}

总结

当写多线程程序时,你可以用volatile得到好处。你必须遵守下面的规则:

* 定义所有的被共享的对象为volatile。

* 不要对基本类型直接用volatile

* 当定义可被共享类时,使用volatile成员函数来表示线程安全。

如果你这样做,而且如果你使用那个简单的返型组件LockingPtr,你能够写出线程安

全的代码而不用更多考虑竟态条件,因为编译器能为你留心,会为你主动指出你错误的地方。

我参与的几个使用volatile和LockingPtr的计划获得很好的效果。代码清晰易懂。我记得碰到几处死锁,但我情愿遇到死锁也不要竟态条件,因为死锁调试起来容易得多。事实上没有遇到任何问题是关于竟态条件的。

关于JavaScript 的好书有哪些

第一本:《JavaScript权威指南》,经典级教材,很厚一本,俗称“犀牛书”,囊括了JS几乎所有的基础知识,新版本还加入了最新的技术内容,适合初学者,有经验的开发者也常常作为随手翻阅的语法书。

第二本:《JavaScript语言精粹》,俗称“蝴蝶书”,是介绍JavaScript语言本质一本书,教你全面了解这门语言的糟粕部分,构建出优雅高效的代码。

第三本:《JavaScript高级程序设计》,这本是我强烈推荐的,是非常经典的JavaScript畅销书,内容全面深入、贴近实战,详细讲解了JavaScript语言的核心,又展示了现有规范及实现以及为开发Web应用提供的各种支持和特性。

谁能详细讲解一下javascript中的srcelement......

srcElement 是Dom事件中的事件最初指派到的元素。

比如有一个div,里面有一个按钮。你响应div的onclick事件,但实际上,你单击的只是它内部的按钮,那么,srcElement指向的,就是那个按钮。

srcElement只在IE中有效。

在Opera系列浏览器中对应的属性是target

给你一个IE下使用的例子。

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""

html xmlns=""

head

title无标题页/title

script type="text/javascript"

function onLoad()

{

document.getElementById( "myDiv" ).attachEvent( "onclick", on_myDivClick );

}

function onUnLoad()

{

document.getElementById( "myDiv" ).detachEvent( "onclick", on_myDivClick );

}

function on_myDivClick( e )

{

if( !e ) e = window.event;

alert( "event: " + e.type + ", fromElement = " + e.srcElement.id );

}

/script

/head

body onload="onLoad()" onunload="onUnLoad()"

div id="myDiv"

input type="button" id="btn1" value="button1" /

input type="button" id="btn2" value="button2" /

/div

/body

/html

如何正确学习JavaScript

学习javascript没HTMl基础有点难度,建议你先熟悉html再学习。

JavaScript简称JS,之前的基础就是HTML,HTML这门课程如果入门的话不是很难,刻苦点一月到两月就能搞定,有HTML基础的话,只要继续刻苦一个月左右JS就能入门,但是想学到高深那就不容易了,js入门后在继续学可以说也是有些难度的。总之先掌握HTML,这是一个基础,正如你说话要先从aoe开始一样,HTML也很容易学的

HTML推荐书籍:深入浅出HTML和CSS

JS推荐书籍:《javascript入门经典》

这些书籍可以帮助你怎么学习,其实不止看书,你也可以看看视频,多看视频讲解学习可以让你少走很多弯路,节省不少时间。遇见问题,常百度一下,现在百度只有你想不到的,没有你查不到的,没有你要的答案,也能查到相关的,何况可以提问嘛……

人就是在不断的问题中解决问题,发现新的问题,继续解决问题,这样自己的自学能力和技术能够得到很大的提升,关键就是不懂一定马上问,千万不要随便拖,这样进步才叫快……

还有补充一下,学习重在实践,因为只有实践你才能更好的发现自己的问题,一个问题解决了,一次不记得,下次继续做的时候再手打一次,但是别抄之前自己写过的代码,除非你觉得自己这段代码已经掌握了,这样为了节省时间才抄,否则还是练练手最好,,万变不离其宗——熟能生巧……

如果你精通了,那就好办了,一个网站可能就被你开发出来,然后就不愁找不到好工作了,至于你认为学到什么地步算精通,这你自己在学习中就可以感受到自己的能力,说的够多了,一时说不完,就这样,最后祝你成功,嘎嘎嘎嘎……


分享文章:讲解javascript,讲解器
文章分享:http://scyanting.com/article/dscepcc.html