Uwaga, ponieważ zestaw 2 ma termin 25-10-2016 to zestaw 1 ma sugerowany termin 18-10 (i to jest zmiana w stosunku do pierwotnej propozycji), jednak z uwagi na to że prawo nie może działać wstecz, zestaw 1 będzie również przyjmowany w terminie 25-10-2016 razem z zestawem 2. Proszę dobrze zaplanować pracę i skorzystać z jednej lub drugiej możliwości.
var foo = {
_i : 0,
get bar() {
return foo._i;
},
set bar(i) {
foo._i = i;
}
}
console.log( foo.bar );
foo.bar = 5;
console.log( foo.bar );
var foo = {
_i : 0,
get bar() {
return foo._i;
},
set bar(i) {
foo._i = i;
}
}
Object.defineProperty( foo, 'qux', {
get : function() {
return 17;
}
});
console.log( foo.qux );
function createGenerator() {
var _state = 0;
return {
next : function() {
return {
value : _state,
done : _state++ >= 10
}
}
}
}
// enumerowanie przez while
var it = createGenerator();
var _result;
while ( _result = it.next(), !_result.done )
console.log( _result.value );
// enumerowanie przez for
var it = createGenerator();
for ( var _result; _result = it.next(), !_result.done; )
console.log( _result.value );
var foo = {
[Symbol.iterator] : createGenerator
};
for ( var f of foo )
console.log(f);
function* createGenerator() {
for ( var _state = 0; _state<10; _state++ )
yield _state;
}
var q = 1;
var p = "qwe";
var s = `ala ${q} ma ${p} kota ${2*q+1}`;
function create(n,s) {
return {
name : n,
surname : s,
say : function() {
return `${this.name} ${this.surname}`;
}
}
}
var p = create('jan', 'kowalski');
console.log( p.say() );
var p = {
name : 'jan',
say : function() {
return this.name;
}
};
var q = Object.create( p );
q.name = 'tomasz';
console.log( q.say() );
var person = {
init : function(name, surname) {
this.name = name;
this.surname = surname;
},
say : function() {
return `${this.name} ${this.surname}`;
}
}
var p = Object.create( person );
p.init( 'jan', 'kowalski' );
console.log( p.say() );
var worker = Object.create( person );
worker.init = function( name, surname, age ) {
// "wywołanie konstruktora klasy bazowej"
person.init.call( this, name, surname );
this.age = age;
}
worker.say = function() {
// "wywołanie metody z klasy bazowej"
var _ = person.say.call( this );
return `${_} ${this.age}`;
}
var w = Object.create( worker );
w.init('tomasz','malinowski',48);
console.log( w.say() );
var Person = function(name, surname) {
this.name = name;
this.surname = surname;
}
Person.prototype.say = function() {
return `${this.name} ${this.surname}`;
}
var p = new Person('jan', 'kowalski');
console.log( p.say() );
var Worker = function(name, surname, age) {
// wywołanie bazowej funkcji konstruktorowej
Person.call( this, name, surname );
this.age = age;
}
// powiązanie łańcucha prototypów
Worker.prototype = Object.create( Person.prototype );
Worker.prototype.say = function() {
// "wywołanie metody z klasy bazowej"
var _ = Person.prototype.say.call( this );
return `${_} ${this.age}`;
}
var w = new Worker('jan', 'kowalski', 48);
console.log( w.say() );
// alternatywa dla new f()
// wyrażona przy pomocy Object.create
function New( f ) {
var _ = Object.create( f.prototype );
// arguments nie jest tablicą więc "pożyczamy" metodę slice od tablicy
var o = f.apply( _, [].slice.call( arguments, 1 ) );
if ( o )
return o;
else
return _;
}
var p = New( Person, 'jan', 'kowalski' );
console.log( p.say() );
// alternatywa dla Object.create( p )
// wyrażona przy pomocy "new"
function ObjectCreate( p ) {
var f = function() { };
f.prototype = p;
return new f();
}
var p = ObjectCreate( person );
p.init('jan', 'kowalski');
console.log( p.say() );
class Person {
constructor(name, surname) {
this.name = name;
this.surname = surname;
}
say() {
return `${this.name} ${this.surname}`;
}
}
class Worker extends Person {
constructor(name, surname, age ) {
super(name, surname);
this.age = age;
}
say() {
// "wywołanie metody z klasy bazowej"
var _ = super.say();
return `${_} ${this.age}`;
}
}
var w = new Worker('tomasz', 'malinowski', 48);
console.log( w.say() );
| C++/Java/C# | Javascript |
|---|---|
| Klasy | Funkcje konstruktorowe |
| Przestrzenie nazw | Obiekty z polami które są referencjami do innych obiektów |
| Składowe prywatne | Umieszczanie elementów w domknięciach funkcji |
| Modularność include/import/using | Modularność require |
npm install typings --global typings install dt~node --global --save
var fs = require('fs');
function read1Sync()
{
var content = fs.readFileSync( './test.txt', 'utf-8' );
console.log( content );
}
read1Sync();
var fs = require('fs');
function read1Async()
{
fs.readFile( './test.txt', 'utf-8',
function( err, data )
{
console.log( data );
}
);
}
read1Async();
var fs = require('fs');
function read1Stream()
{
var buf ='';
var s = fs.createReadStream( './test.txt', { encoding :'utf-8' } );
s.on( 'data', function(data) {
buf += data.toString();
});
s.on('end', function() {
console.log( buf );
});
}
read1Stream();
var fs = require('fs');
function read1Stream()
{
var buf ='';
var s = fs.createReadStream( './test.txt', { encoding :'utf-8' } );
s.pipe( process.stdout );
}
read1Stream();
function fspromise(path) {
return new Promise( function( res, rej ) {
fs.readFile(path, function(err, data) {
if ( err )
rej(err );
res( data.toString() );
});
} );
}
var f1 = fspromise('./alamakota.txt');
var f2 = fspromise('./alamakota2.txt');
var f3 = Promise.all([f1,f2])
.then(function(results) {
console.log( results )
} );
function promiseall(p1, p2) {
return p1.then(function(p1r) {
return p2.then(function(p2r) {
return new Promise( function(res, rej) {
res([p1r,p2r]);
});
});
});
}
// poniższy kod dziś jeszcze nie wykona się poprawnie
// funkcja oznakowana jako async
// zwraca Promise
async function promisedGet(url) {
return new Promise(function (resolve, reject) {
var client = http.get(url, function (res) {
var buffer = '';
res
.on('data', function (data) {
buffer += data.toString();
})
.on('end', function () {
resolve(buffer);
});
});
});
}
// funkcja oznakowana jako async,
// wolno w niej wywoływać inną funkcję zwracającą Promise przez await
async function foo() {
// await ___ ...
var result = await promisedGet('http://www.google.pl');
console.log( result );
// jest równoważne dzisiejszemu
//
// promistedGet('http://www.google.pl')
// .then( function(result) { console.log( result );} );
//
// a umieszczeniem całego kodu napisanego "pod" await w kontynuacji
// doczepionej do Promise przez then zajmuje się już sam kompilator
}
foo();
npm init -y npm install express --save npm install ejs --save
var http = require('http');
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
app.set('views', './views');
// tu dodajemy middleware
...
// tu uruchamiamy serwer
var server = http.createServer(app).listen(3000);
console.log( 'serwer started' );
<html>
<body>
<% var foo = 'bar' %>
<% for ( var i=0; i<5; i++ ) { %>
<input value='<%= i %>' />
<% } %>
</body>
</html>
app.get('/', (req, res) => {
var model = { user : 'jan' };
res.render('user', model);
});
// user.ejs
<html>
<body>
Użytkownik : <%= user %>
</body>
</html>
app.get('/przelewy', (req, res) => {
var przelewy = [
{ kwota : 123, data : '2016-01-03', id = 1 },
{ kwota : 124, data : '2016-01-02', id = 2 },
{ kwota : 125, data : '2016-01-01', id = 3 },
];
res.render('przelewy', { przelewy : przelewy } );
});
// przelewy.ejs
<html>
<body>
<table>
<tr>
<th>Data</th>
<th>Kwota</th>
<th></th>
</tr>
<% przelewy.forEach( przelew => { %>
<tr>
<td><%= przelew.data %></td>
<td><%= przelew.kwota %></td>
<td><a href='/przelew/<%= przelew.id %>'>Więcej</a></td>
</tr>
<% }) %>
</table>
</body>
</html>
app.use((req,res,next) => {
res.render('404.ejs', { url : req.url });
});
// 404.ejs
<html>
<body>
Strona <%= url %> nie została znaleziona.
</body>
</html>
res.redirect('innastrona');
żądanie do http://localhost:3000/strona?p1=v1&p2=v2
app.get('/strona', (req, res) => {
var p1 = req.query.p1;
var p2 = req.query.p2;
});
Uwaga na możliwy atak Querystring Tamepring
app.get('/przelew/:id', (req, res) => {
var id = req.params.id;
res.render('przelew', { id : id } );
});
app.get('/plik', (req, res) => {
// proszę zaremować i odremować tę linijkę i porównać wynik
res.setHeader('Content-disposition', 'attachment; filename=plik.txt');
res.write('123');
res.end();
});
npm install body-parser --save
var bodyParser = require('body-parser');
app.use( bodyParser.urlencoded({extended:true}) ) ;
app.get('/login', (req, res) => {
res.render('login');
});
app.post('/login', (req, res) => {
var username = req.body.username;
var pwd = req.body.pwd;
});
// login.ejs
<html>
<body>
<form method="POST">
<div>
Login: <input type='text' name='username' />
</div>
<div>
Password: <input type='password' name='pwd' />
</div>
<div>
<button>Login</button>
</div>
</form>
</body>
</html>
// instalacja middleware
app.use( express.static('./static'));
Od tego momentu wszystkie pliki w folderze '/static' są serwowane na żądania adresowane przez '/', np. do pliku
'/static/app.css' odwołamy się przez
<link rel='stylesheet' href='/app.css'>
// instalacja middleware
npm install cookie-parser --save
// w aplikacji
var cookieParser = require('cookie-parser');
app.use( cookieParser() );
// wydanie ciastka
res.cookie('foo', 'bar');
// sprawdzenie ciastka
req.cookies.foo;
// wydanie ciastka
res.cookie('foo', 'bar', { maxAge : 60 * 1000 } ); // 60 sekund
// usunięcie ciastka z przeglądarki
res.cookie('foo', '', { maxAge : -1 } );
// w aplikacji
var cookieParser = require('cookie-parser');
app.use( cookieParser('9877dg9fb8sd79b87sdt9b87ds98b') ); // secret
// wydanie ciastka
res.cookie('foo', 'bar', { signed : true });
// sprawdzenie ciastka
req.signedCookies.foo;
// instalacja middleware npm install express-session --save // dodawanie danych do sesji req.session.foo = 'bar'; // odczyt danych z sesji var foo = req.session.foo;
app.get('/', (req, res) => {
if ( !req.cookie.user )
res.redirect('/login');
else
...
});
// middleware logowania
function authorize(req, res, next) {
if ( req.cookies.user ) {
// użytkownik jest zalogowany
// "przepisanie" danych użytkownika żeby dostęp był jednolity
req.user = req.cookies.user;
next();
} else {
// użytkownik niezalogowany
// przekierowanie z zapamiętaniem strony która spowodowała przekierowanie
res.redirect( '/login?returnUrl='+req.url);
}
}
// wymuszenie logowania na konkretnym zasobie
app.get('/', authorize, (req, res) => {
// to wykona się tylko jeśli middleware authorize przejdzie przez ścieżkę zalogowanego użytkownika
// w przeciwnym przypadku żądanie zostanie tam przekierowane na /login?returnUrl=/
});
// logowanie
app.get('/login', (req, res) => {
// wyrenderuj stronę logowania
res.render('login');
});
app.post('/login', (req, res) => {
// użytkownik kliknął przycisk "zaloguj" na stronie logowania (POST)
var username = req.body.txtUser; // na stronie jest <input type='text' name='txtUser' ...
var pwd = req.body.txtPwd; // na stronie jest <input type='password' name='txtPwd' ...
if ( username == pwd ) { // w rzeczywistości - sprawdzenie w bazie danych
res.cookie('user', username); // wydanie ciastka, od tego momentu użytkownik jest zalogowany
var returnUrl = req.query.returnUrl;
res.redirect( returnUrl ); // powrót do miejsca z którego nastąpiło przekierowanie tutaj
} else {
// nie udało się zalogować, trzeba znów pokazać stronę logowania z komunikatem
res.render('login', { message : 'Zła nazwa logowania lub hasło' });
}
});
npm installżeby dociągnąć wszystkie pakiety wymienione w package.json.
// select.ejs
<select name='<%= name %>'>
<% options.forEach( option => { %>
<option value='<%= option.value %>'><%= option.text %></option>
<% }) %>
</select>
// wywołanie szablonu z innego szablonu
<% var name='combo1' %>
<% var options= [
{ value : 1, text : 'element 1' },
{ value : 2, text : 'element 2' },
{ value : 3, text : 'element 3' }
]
%>
<% include select %>
git init git add . git commit -m “initial commit” heroku login heroku create git push heroku master
CREATE TABLE [dbo].[Child]( [ID] [int] IDENTITY(1,1) NOT NULL, [ChildName] [nvarchar](150) NOT NULL, [ID_PARENT] [int] NOT NULL, CONSTRAINT [PK_Child] PRIMARY KEY CLUSTERED ( [ID] ASC ) ) ON [PRIMARY] GO CREATE TABLE [dbo].[Parent]( [ID] [int] IDENTITY(1,1) NOT NULL, [ParentName] [nvarchar](150) NOT NULL, CONSTRAINT [PK_Parent] PRIMARY KEY CLUSTERED ( [ID] ASC ) ) ON [PRIMARY] ALTER TABLE [dbo].[Child] WITH CHECK ADD CONSTRAINT [FK_Child_Parent] FOREIGN KEY([ID_PARENT]) REFERENCES [dbo].[Parent] ([ID])
var conn = new sql.Connection('server=localhost,1433;database=database2;user id=foo;password=foo');
conn.connect()
.then( () => {
var request = new sql.Request(conn);
request.query('select * from Parent')
.then( recordset => {
res.contentType('text/html');
recordset.forEach( r => {
res.write( `${r.ID} ${r.ParentName}<br/>`);
});
conn.close();
res.end();
})
.catch( err => {
console.log( err );
});
})
.catch( err => {
console.log(err);
});
try {
var conn = new sql.Connection('server=localhost,1433;database=database2;user id=foo;password=foo');
await conn.connect();
var request = new sql.Request(conn);
var recordset = await request.query('select * from Parent')
res.contentType('text/html');
recordset.forEach( r => {
res.write( `${r.ID} ${r.ParentName}<br/>`);
});
conn.close();
res.end();
}
catch ( err ) {
console.log( err );
}
Proszę zwrócić uwagę na to że te kilka tygodni ciężko pracowaliśmy na to żeby móc w końcu pisać taki "liniowy", normalny kod,
bez asynchronicznych callbacków i bez zamykania kodu kontynuacji w Promise().then(...) - wszędzie tam gdzie pojawia się
promise().then( result => {
});
można aktualnie napisać
var result = await promise();
// /repo/parentRepo
module.exports.insert = async function(conn, parent) {
try {
var req = new sql.Request(conn);
req.input("ParentName", parent.parentName);
var recordset = await req.query( "insert into Parent (ParentName) values (@ParentName) select scope_identity() as id");
return recordset[0].id;
}
catch ( err ) {
// cokolwiek, włącznie z throw err;
}
}
var assert = require('assert');
describe('Top level', function() {
describe('Sub level', function() {
it( 'Unit test function definition', function() {
assert.equal( -1, [1,2,3].indexOf(4) );
});
});
});
var webdriverio = require('webdriverio');
var options = { desiredCapabilities: { browserName: 'chrome' } };
var client = webdriverio.remote(options);
client
.init()
.url('https://duckduckgo.com/')
.setValue('#search_form_input_homepage', 'WebdriverIO')
.click('#search_button_homepage')
.getTitle().then(function(title) {
console.log('Title is: ' + title);
// outputs: "Title is: WebdriverIO (Software) at DuckDuckGo"
})
.end();